Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
MessageCorrelation örneği, Message Queuing (MSMQ) uygulamasının bir Windows Communication Foundation (WCF) hizmetine MSMQ iletisi gönderebildiğini ve bir istek/yanıt senaryosunda iletilerin gönderen ve alıcı uygulamalar arasında nasıl ilişkilendirilebileceğini gösterir. Bu örnek msmqIntegrationBinding bağlamasını kullanır. Bu durumda hizmet, kuyruğa alınmış mesajları alan hizmeti gözlemlemenizi sağlayan kendi kendine barındırılan bir konsol uygulamasıdır. k
Hizmet, gönderenden alınan iletiyi işler ve gönderene bir yanıt iletisi gönderir. Gönderen, aldığı yanıtla başlangıçta gönderdiği istek arasında bağıntı oluşturur. İletinin MessageID ve CorrelationID özellikleri, istek ve yanıt iletilerini ilişkilendirmek için kullanılır.
Hizmet IOrderProcessor sözleşmesi, kuyruğa alma ile kullanıma uygun tek yönlü bir hizmet işlemi tanımlar. MSMQ iletisinin Eylem üst bilgisi yoktur, bu nedenle farklı MSMQ iletilerini işlem sözleşmelerine otomatik olarak eşlemek mümkün değildir. Bu nedenle, bu durumda yalnızca bir işlem sözleşmesi olabilir. Hizmette daha fazla işlem sözleşmesi tanımlamak istiyorsanız, uygulamanın MSMQ iletisindeki hangi başlık bilgisinin (örneğin, etiket veya bağıntı kimliği) hangi işlem sözleşmesinin iletileceğine karar vermek için kullanılabileceğini belirtmesi gerekir.
MSMQ iletisi, üst bilgilerin işlem sözleşmesinin farklı parametreleriyle eşlendiği bilgileri de içermez. Bu nedenle, işlem sözleşmesinde yalnızca bir parametre olabilir. Parametre, temel alınan MSMQ iletisini içeren MsmqMessage<T> türündedir. sınıfındaki MsmqMessage<T> "T" türü MSMQ ileti gövdesinde seri hale getirilmiş verileri temsil eder. Bu örnekte, PurchaseOrder türü MSMQ mesaj gövdesine serileştirilir.
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
[ServiceKnownType(typeof(PurchaseOrder))]
public interface IOrderProcessor
{
[OperationContract(IsOneWay = true, Action = "*")]
void SubmitPurchaseOrder(MsmqMessage<PurchaseOrder> msg);
}
Servis işlemi, satın alma siparişini işler ve satınalma siparişinin içeriğini ve durumunu hizmet konsolu penceresinde görüntüler.
OperationBehaviorAttribute işlemi kuyruk ile bir işlemde listelemek ve operasyon geri döndüğünde, işlemi tamamlandı olarak işaretlemek üzere yapılandırıyor. , PurchaseOrder hizmet tarafından işlenmesi gereken sipariş ayrıntılarını içerir.
// Service class that implements the service contract.
public class OrderProcessorService : IOrderProcessor
{
[OperationBehavior(TransactionScopeRequired = true,
TransactionAutoComplete = true)]
public void SubmitPurchaseOrder(MsmqMessage<PurchaseOrder> ordermsg)
{
PurchaseOrder po = (PurchaseOrder)ordermsg.Body;
Random statusIndexer = new Random();
po.Status = PurchaseOrder.OrderStates[statusIndexer.Next(3)];
Console.WriteLine("Processing {0} ", po);
//Send a response to the client that the order has been received
// and is pending fulfillment.
SendResponse(ordermsg);
}
private void SendResponse(MsmqMessage<PurchaseOrder> ordermsg)
{
OrderResponseClient client = new OrderResponseClient("OrderResponseEndpoint");
//Set the correlation ID such that the client can correlate the response to the order.
MsmqMessage<PurchaseOrder> orderResponseMsg = new MsmqMessage<PurchaseOrder>(ordermsg.Body);
orderResponseMsg.CorrelationId = ordermsg.Id;
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
client.SendOrderResponse(orderResponseMsg);
scope.Complete();
}
client.Close();
}
}
Hizmet, kuyruğa MSMQ iletisi göndermek için özel bir istemci OrderResponseClient kullanır. İletiyi alan ve işleyen uygulama WCF uygulaması değil MSMQ uygulaması olduğundan, iki uygulama arasında örtük bir hizmet sözleşmesi yoktur. Bu nedenle bu senaryoda Svcutil.exe aracını kullanarak ara sunucu oluşturamıyoruz.
Özel ara sunucu temelde, iletileri göndermek için bağlamayı msmqIntegrationBinding kullanan tüm WCF uygulamaları için aynıdır. Diğer proxy'lerden farklı olarak, bir dizi hizmet işlemi içermez. Yalnızca ileti gönderme işlemidir.
[System.ServiceModel.ServiceContractAttribute(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface IOrderResponse
{
[System.ServiceModel.OperationContractAttribute(IsOneWay = true, Action = "*")]
void SendOrderResponse(MsmqMessage<PurchaseOrder> msg);
}
public partial class OrderResponseClient : System.ServiceModel.ClientBase<IOrderResponse>, IOrderResponse
{
public OrderResponseClient()
{ }
public OrderResponseClient(string configurationName)
: base(configurationName)
{ }
public OrderResponseClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress address)
: base(binding, address)
{ }
public void SendOrderResponse(MsmqMessage<PurchaseOrder> msg)
{
base.Channel.SendOrderResponse(msg);
}
}
Hizmet kendi sunucunuzda barındırılır. MSMQ tümleştirme aktarımı kullanılırken, kullanılan kuyruk önceden oluşturulmalıdır. Bu, el ile veya kod aracılığıyla yapılabilir. Bu örnekte hizmet, kuyruğun varlığını denetlemek ve gerekirse oluşturmak için kod içerir System.Messaging . Kuyruk adı yapılandırma dosyasından okunur.
public static void Main()
{
// Get the MSMQ queue name from application settings in configuration.
string queueName =
ConfigurationManager.AppSettings["orderQueueName"];
// Create the transacted MSMQ queue if necessary.
if (!MessageQueue.Exists(queueName))
MessageQueue.Create(queueName, true);
// Create a ServiceHost for the OrderProcessorService type.
using (ServiceHost serviceHost = new
ServiceHost(typeof(OrderProcessorService)))
{
serviceHost.Open();
// The service can now be accessed.
Console.WriteLine("The service is ready.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.ReadLine();
// Close the ServiceHost to shutdown the service.
serviceHost.Close();
}
}
Sipariş isteklerinin gönderildiği MSMQ kuyruğu, yapılandırma dosyasının appSettings bölümünde belirtilir. İstemci ve hizmet uç noktaları, yapılandırma dosyasının system.serviceModel bölümünde tanımlanır. Her ikisi de bağlantıyı msmqIntegrationBinding belirtir.
<appSettings>
<add key="orderQueueName" value=".\private$\Orders" />
</appSettings>
<system.serviceModel>
<client>
<endpoint name="OrderResponseEndpoint"
address="msmq.formatname:DIRECT=OS:.\private$\OrderResponse"
binding="msmqIntegrationBinding"
bindingConfiguration="OrderProcessorBinding"
contract="Microsoft.ServiceModel.Samples.IOrderResponse">
</endpoint>
</client>
<services>
<service
name="Microsoft.ServiceModel.Samples.OrderProcessorService">
<endpoint address="msmq.formatname:DIRECT=OS:.\private$\Orders"
binding="msmqIntegrationBinding"
bindingConfiguration="OrderProcessorBinding"
contract="Microsoft.ServiceModel.Samples.IOrderProcessor">
</endpoint>
</service>
</services>
<bindings>
<msmqIntegrationBinding>
<binding name="OrderProcessorBinding" >
<security mode="None" />
</binding>
</msmqIntegrationBinding>
</bindings>
</system.serviceModel>
İstemci uygulaması, System.Messaging kullanarak kuyruğa dayanıklı ve işlemsel bir ileti gönderir. İletinin gövdesi satın alma siparişini içerir.
static void PlaceOrder()
{
//Connect to the queue
MessageQueue orderQueue =
new MessageQueue(
ConfigurationManager.AppSettings["orderQueueName"])
// Create the purchase order.
PurchaseOrder po = new PurchaseOrder();
po.CustomerId = "somecustomer.com";
po.PONumber = Guid.NewGuid().ToString();
PurchaseOrderLineItem lineItem1 = new PurchaseOrderLineItem();
lineItem1.ProductId = "Blue Widget";
lineItem1.Quantity = 54;
lineItem1.UnitCost = 29.99F;
PurchaseOrderLineItem lineItem2 = new PurchaseOrderLineItem();
lineItem2.ProductId = "Red Widget";
lineItem2.Quantity = 890;
lineItem2.UnitCost = 45.89F;
po.orderLineItems = new PurchaseOrderLineItem[2];
po.orderLineItems[0] = lineItem1;
po.orderLineItems[1] = lineItem2;
Message msg = new Message();
msg.UseDeadLetterQueue = true;
msg.Body = po;
//Create a transaction scope.
using (TransactionScope scope = new
TransactionScope(TransactionScopeOption.Required))
{
// Submit the purchase order.
orderQueue.Send(msg, MessageQueueTransactionType.Automatic);
// Complete the transaction.
scope.Complete();
}
//Save the messageID for order response correlation.
orderMessageID = msg.Id;
Console.WriteLine("Placed the order, waiting for response...");
}
Sipariş yanıtlarının alındığı MSMQ kuyruğu, aşağıdaki örnek yapılandırmada gösterildiği gibi yapılandırma dosyasının appSettings bölümünde belirtilir.
Uyarı
Kuyruk adı, yerel bilgisayar için nokta (.) ve yolunda ters eğik çizgi ayırıcıları kullanır. WCF uç noktası adresi bir msmq.formatname şeması belirtir ve yerel bilgisayar için "localhost" kullanır. Düzgün biçimlendirilmiş biçim adı, MSMQ yönergelerine göre URI'deki msmq.formatname dosyasını izler.
<appSettings>
<add key=" orderResponseQueueName" value=".\private$\Orders" />
</appSettings>
İstemci uygulaması, hizmete gönderdiği sipariş isteği iletisini kaydeder messageID ve hizmetten bir yanıt bekler. Bir yanıt kuyruğa ulaştığında istemci, istemcinin başlangıçta hizmete gönderdiği sipariş iletisini içeren correlationID iletinin özelliğini kullanarak messageID gönderdiği sipariş iletisiyle bağıntı kurar.
static void DisplayOrderStatus()
{
MessageQueue orderResponseQueue = new
MessageQueue(ConfigurationManager.AppSettings
["orderResponseQueueName"]);
//Create a transaction scope.
bool responseReceived = false;
orderResponseQueue.MessageReadPropertyFilter.CorrelationId = true;
while (!responseReceived)
{
Message responseMsg;
using (TransactionScope scope2 = new
TransactionScope(TransactionScopeOption.Required))
{
//Receive the Order Response message.
responseMsg =
orderResponseQueue.Receive
(MessageQueueTransactionType.Automatic);
scope2.Complete();
}
responseMsg.Formatter = new
System.Messaging.XmlMessageFormatter(new Type[] {
typeof(PurchaseOrder) });
PurchaseOrder responsepo = (PurchaseOrder)responseMsg.Body;
//Check if the response is for the order placed.
if (orderMessageID == responseMsg.CorrelationId)
{
responseReceived = true;
Console.WriteLine("Status of current Order: OrderID-{0},Order
Status-{1}", responsepo.PONumber, responsepo.Status);
}
else
{
Console.WriteLine("Status of previous Order: OrderID-{0},Order
Status-{1}", responsepo.PONumber, responsepo.Status);
}
}
}
Örneği çalıştırdığınızda, istemci ve hizmet etkinlikleri hem hizmet hem de istemci konsol pencerelerinde görüntülenir. Hizmetin istemciden ileti aldığını ve istemciye bir yanıt gönderdiğini görebilirsiniz. İstemci, hizmetten alınan yanıtı görüntüler. Hizmeti ve istemciyi kapatmak için her konsol penceresinde ENTER tuşuna basın.
Uyarı
Bu örnek, Message Queuing 'in (MSMQ) yüklenmesini gerektirir. Ayrıca Bkz bölümündeki MSMQ yükleme yönergelerine bakın.
Örneği ayarlama, derleme ve çalıştırma
Windows Communication Foundation Örnekleri içinOne-Time Kurulum Yordamını yaptığınızdan emin olun.
Hizmet önce çalıştırılırsa, kuyruğun mevcut olup olmadığını kontrol eder. Kuyruk mevcut değilse, hizmet tarafından bir kuyruk oluşturulacaktır. Kuyruğu oluşturmak için önce hizmeti çalıştırabilir veya MSMQ Kuyruk Yöneticisi aracılığıyla bir kuyruk oluşturabilirsiniz. Windows 2008'de kuyruk oluşturmak için bu adımları izleyin.
Visual Studio 2012'de Sunucu Yöneticisi'nin açılması.
Özellikler sekmesini genişletin.
Özel İleti Kuyruklarısağ tıklayın ve Yeni, Özel Kuyrukseçin.
İşlem kutusunu işaretleyin.
Yeni kuyruğun adı olarak
ServiceModelSamplesTransactedgirin.
Çözümün C# veya Visual Basic .NET sürümünü oluşturmak için Windows Communication Foundation Örneklerioluşturma başlığındaki yönergeleri izleyin.
Örneği tek bilgisayarlı bir yapılandırmada çalıştırmak için Windows Communication Foundation Örneklerini Çalıştırma başlığındaki yönergeleri izleyin.
Örneği bilgisayarlar arasında çalıştırma
\service\bin\ klasöründeki, dile özgü klasörün altındaki hizmet programı dosyalarını hizmet bilgisayarına kopyalayın.
\client\bin\ klasöründeki, dile özgü klasörün altındaki istemci program dosyalarını istemci bilgisayara kopyalayın.
Client.exe.config dosyasında orderQueueName değerini değiştirerek "." yerine hizmet bilgisayarı adını belirtin.
Service.exe.config dosyasında, istemci uç noktası adresini "." yerine istemci bilgisayar adını belirtecek şekilde değiştirin.
Hizmet bilgisayarında bir komut isteminden Service.exe başlatın.
İstemci bilgisayarda bir komut isteminden Client.exe başlatın.
Ayrıca bakınız
- WCF 'de Kuyruğa Alma
- İleti Kuyruğa Alma