MSMQ 啟動
這個範例示範如何在 Windows Process Activation Service (WAS) 中裝載可從訊息佇列讀取的應用程式。這個範例會使用 netMsmqBinding,並且以雙向通訊範例為基礎。本例中的服務是 Web 裝載的應用程式,而用戶端則會自我裝載並輸出至主控台,以便觀察所送出採購單的狀態。
![]() |
---|
此範例的安裝程序與建置指示位於本主題的結尾。 |
Windows Process Activation Service (WAS) 是 Windows Server 2008 上全新的處理序啟動機制,可以為使用非 HTTP 通訊協定的應用程式提供類似 IIS 的功能,而這些功能原先只有 HTTP 應用程式才能使用。Windows Communication Foundation (WCF) 會使用「接聽程式配接器」介面來傳達啟動要求,而這些要求是透過 WCF 支援的非 HTTP 通訊協定 (例如,TCP、具名管道和 MSMQ) 來接收。SMSvcHost.exe 中執行的 Managed Windows 服務會裝載可透過非 HTTP 通訊協定接收要求的功能。
Net.Msmq 接聽程式配接器服務 (NetMsmqActivator) 會根據佇列中的訊息啟動佇列應用程式。
用戶端會將採購單從交易範圍內傳送至服務。服務則在交易中接收訂單,然後加以處理。服務以訂單的狀態來回呼用戶端。為了促進雙向通訊,用戶端與服務都會使用佇列將採購單和訂單狀態加入佇列。
服務合約 IOrderProcessor
會定義適合與佇列一起使用的單向服務作業。服務作業使用回覆端點,將訂單狀態傳送至用戶端。回覆端點的位址是用來將訂單狀態傳回用戶端的佇列 URI。訂單處理應用程式會實作這個合約。
[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface IOrderProcessor
{
[OperationContract(IsOneWay = true)]
void SubmitPurchaseOrder(PurchaseOrder po,
string reportOrderStatusTo);
}
用戶端會指定要將訂單狀態傳送到其中的回覆合約。用戶端會實作訂單狀態合約。服務則使用這個合約產生的用戶端將訂單狀態傳回用戶端。
[ServiceContract]
public interface IOrderStatus
{
[OperationContract(IsOneWay = true)]
void OrderStatus(string poNumber, string status);
}
服務作業會處理已送出的採購單。OperationBehaviorAttribute 會套用至服務作業以便在用來從佇列接收訊息的交易中指定自動進行登記,以及在服務作業完成時自動完成交易。Orders
類別會封裝訂單處理功能。在本例中,這個類別會將採購單新增至字典。Orders
類別中的作業可以使用服務作業所登記的交易。
服務作業除了處理已送出的採購單外,也會將訂單狀態回覆至用戶端。
public class OrderProcessorService : IOrderProcessor
{
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public void SubmitPurchaseOrder(PurchaseOrder po, string reportOrderStatusTo)
{
Orders.Add(po);
Console.WriteLine("Processing {0} ", po);
Console.WriteLine("Sending back order status information");
NetMsmqBinding msmqCallbackBinding = new NetMsmqBinding();
msmqCallbackBinding.Security.Mode = NetMsmqSecurityMode.None;
OrderStatusClient client = new OrderStatusClient(msmqCallbackBinding, new EndpointAddress(reportOrderStatusTo));
// please note that the same transaction that is used to dequeue purchase order is used
// to send back order status
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
client.OrderStatus(po.PONumber, po.Status);
scope.Complete();
}
}
您可以使用組態檔來指定要使用的用戶端繫結。
MSMQ 佇列名稱是指定在組態檔的 appSettings 區段中。服務端點會定義在組態檔的 System.serviceModel 區段中。
![]() |
---|
MSMQ 佇列名稱與端點位址會使用稍微不同的定址慣例。MSMQ 佇列名稱會使用點 (.) 來代表本機電腦,並在其路徑中使用反斜線分隔符號。WCF 端點位址會指定 net.msmq: 配置、使用代表本機電腦的 "localhost",以及在其路徑中使用正斜線。若要讀取裝載於遠端電腦的佇列,請將 "." 和 "localhost" 取代為遠端電腦名稱。 |
帶有類別名稱的 .svc 檔案會用來裝載 WAS 中的服務程式碼。
Service.svc 檔案本身含有要建立 OrderProcessorService
的指示詞。
<%@ServiceHost language="c#" Debug="true" Service="Microsoft.ServiceModel.Samples.OrderProcessorService"%>
Service.svc 檔案還包含組件指示詞,可確保載入 System.Transactions.dll。
<%@Assembly name="System.Transactions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"%>
用戶端會建立一個交易範圍。與服務的通訊會在交易範圍內進行,形成不可部分完成的原子單位 (Atomic Unit),其中的訊息若不是全部成功,就是全部失敗。呼叫交易範圍上的 Complete,即可認可交易。
using (ServiceHost serviceHost = new ServiceHost(typeof(OrderStatusService)))
{
// Open the ServiceHostBase to create listeners and start listening
// for order status messages.
serviceHost.Open();
// Create a proxy with given client endpoint configuration
OrderProcessorClient client = new OrderProcessorClient();
// 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;
//Create a transaction scope.
using (TransactionScope scope = new
TransactionScope(TransactionScopeOption.Required))
{
// Make a queued call to submit the purchase order
client.SubmitPurchaseOrder(po,
"net.msmq://localhost/private/ServiceModelSamples/OrderStatus");
// Complete the transaction.
scope.Complete();
}
//Closing the client gracefully closes the connection and cleans up
//resources
client.Close();
Console.WriteLine();
Console.WriteLine("Press <ENTER> to terminate client.");
Console.ReadLine();
// Close the ServiceHostBase to shutdown the service.
serviceHost.Close();
}
用戶端程式碼會實作 IOrderStatus
合約以接收服務的訂單狀態。在此範例中,它會印出訂單狀態。
[ServiceBehavior]
public class OrderStatusService : IOrderStatus
{
[OperationBehavior(TransactionAutoComplete = true,
TransactionScopeRequired = true)]
public void OrderStatus(string poNumber, string status)
{
Console.WriteLine("Status of order {0}:{1} ",
poNumber , status);
}
}
訂單狀態佇列會建立在 Main
方法中。用戶端組態會包含訂單狀態服務組態來裝載訂單狀態服務,如下列範例組態所示。
<appSettings>
<!-- use appSetting to configure MSMQ queue name -->
<add key="targetQueueName" value=".\private$\ServiceModelSamples/service.svc" />
<add key="responseQueueName" value=".\private$\ServiceModelSamples/OrderStatus" />
</appSettings>
<system.serviceModel>
<services>
<service
name="Microsoft.ServiceModel.Samples.OrderStatusService">
<!-- Define NetMsmqEndpoint -->
<endpoint address="net.msmq://localhost/private/ServiceModelSamples/OrderStatus"
binding="netMsmqBinding"
contract="Microsoft.ServiceModel.Samples.IOrderStatus" />
</service>
</services>
<client>
<!-- Define NetMsmqEndpoint -->
<endpoint name="OrderProcessorEndpoint"
address="net.msmq://localhost/private/ServiceModelSamples/service.svc"
binding="netMsmqBinding"
contract="Microsoft.ServiceModel.Samples.IOrderProcessor" />
</client>
</system.serviceModel>
當您執行範例時,用戶端與服務活動都會顯示在伺服器與用戶端主控台視窗中。您可以看到伺服器從用戶端接收訊息。在每一個主控台視窗中按 ENTER 鍵,即可關閉伺服器與用戶端。
用戶端會顯示伺服器傳送的訂單狀態資訊。
Press <ENTER> to terminate client.
Status of order 70cf9d63-3dfa-4e69-81c2-23aa4478ebed :Pending
若要設定、建置及執行範例
請確定您已執行 Windows Communication Foundation 範例的單次安裝程序。此外,您必須安裝 WCF 非 HTTP 啟動元件:
- 在 [開始] 功能表內選擇 [控制台]。
- 依序選取 [程式集] 和 [程式和功能],或在傳統檢視中選取 [程式和功能]。
- 按一下 [開啟或關閉 Windows 功能]。
- 按一下 [功能摘要] 下的 [新增功能]。
- 展開 [Microsoft .NET Framework 3.0] 節點,然後核取 [Windows Communication Foundation 非 HTTP 啟動] 功能。
若要建置方案的 C# 或 Visual Basic .NET 版本,請遵循建置 Windows Communication Foundation 範例中的指示。
從命令視窗執行 client.exe,以執行用戶端。這會建立佇列,並將訊息傳送給它。讓用戶端繼續執行,以便查看服務讀取訊息的結果。
根據預設,MSMQ 啟動服務會以網路服務的身分執行。因此,用來啟動應用程式的佇列必須讓「網路服務」擁有接收和查看其中訊息的權限。您可以使用訊息佇列 MMC 來新增此權限:
- 在 [開始] 功能表中按一下 [執行],然後輸入 Compmgmt.msc,再按下 ENTER。
- 展開 [服務及應用程式] 下的 [訊息佇列]。
- 按一下 [私用佇列]。
- 以滑鼠右鍵按一下佇列 (servicemodelsamples/Service.svc),再選擇 [屬性]。
- 在 [安全性] 索引標籤上,按一下 [新增],並將查看和接收權限授與「網路服務」。
設定 Windows Process Activation Service (WAS) 以支援 MSMQ 啟動。
- 執行 Inetmgr.exe。
- 若要啟用預設網站以透過 net.msmq 通訊協定進行通訊,您必須新增網站繫結。若要這麼做,請執行範例目錄中的命令檔 AddMsmqSiteBinding.cmd。
如果您之前未曾這麼做,請確定 MSMQ 啟動服務已啟用。在 [開始] 功能表中按一下 [執行],然後輸入 Services.msc。搜尋 Net.Msmq Listener Adapter 的服務清單。按一下滑鼠右鍵並選取 [屬性]。將 [啟動類型] 設定為 [自動],然後按一下 [套用] 和 [啟動] 按鈕。這個步驟只需要在第一次使用 Net.Msmq 接聽程式配接器服務之前執行一次。
若要在單一或跨電腦的組態中執行本範例,請遵循執行 Windows Communication Foundation 範例中的指示。此外,還要在發送採購單的用戶端上變更程式碼,以便在送出採購單時將電腦名稱反映於佇列的 URI。請使用下列程式碼:
client.SubmitPurchaseOrder(po, "net.msmq://localhost/private/ServiceModelSamples/OrderStatus");
根據預設,安全性會透過 netMsmqBinding 繫結傳輸啟用。MsmqAuthenticationMode 和 MsmqProtectionLevel 這兩個屬性會共同決定傳輸安全性的類型。根據預設,驗證模式會設定為 Windows,保護層級則會設定為 Sign。若要 MSMQ 提供驗證和簽署功能,則 MSMQ 必須是網域的一部分。如果您在不屬於網域的電腦上執行這個範例,就會收到下列錯誤:「使用者的內部訊息佇列憑證不存在」。
若要在加入至工作群組的電腦上執行範例
如果您的電腦不是網域的一部分,請將驗證模式和保護層級設定為 None,以關閉傳輸安全性,如下面的範例組態所示:
<bindings> <netMsmqBinding> <binding configurationName="TransactedBinding"> <security mode="None"/> </binding> </netMsmqBinding> </bindings>
請先變更伺服器與用戶端上的組態,再執行範例。
注意:
將 security mode 設定為 None,相當於將 MsmqAuthenticationMode、MsmqProtectionLevel 和 Message 安全性設定為 None。 若要在已加入工作群組的電腦中啟用啟動作業,則啟動服務和背景工作處理序都必須透過特定使用者帳戶 (這兩者的帳戶必須相同) 來執行,而且佇列必須具有特定使用者帳戶的 ACL。
若要變更背景工作處理序用以執行的身分識別:
- 執行 Inetmgr.exe。
- 在 [應用程式集區] 下,以滑鼠右鍵按一下 [AppPool] (通常是 DefaultAppPool),然後選擇 [設定應用程式集區預設值…]。
- 變更身分識別屬性以使用特定的使用者帳戶。
若要變更啟動服務用以執行的身分識別:
- 執行 Services.msc。
- 以滑鼠右鍵按一下 [Net.MsmqListener 配接器],然後選擇 [屬性]。
變更 [登入] 索引標籤中的帳戶。
在工作群組中,服務還必須使用不受限制的權杖來執行。若要這麼做,請在命令視窗中執行下列命令:
sc sidtype netmsmqactivator unrestricted
Send comments about this topic to Microsoft.
© 2007 Microsoft Corporation. All rights reserved.