[英]WCF not processing MSMQ message with binary format
我有一個WCF Windows服務,可以檢索MSMQ消息。 似乎未調用SubmitPurchaseOrderInMessage,在隊列中也看不到任何消息。 代碼如下所示。
WCF類:
public class OrderProcessorService : IOrderProcessor
{
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
[ServiceKnownType(typeof(MyOrder))]
public void SubmitPurchaseOrderInMessage(MsmqMessage<MyOrder> ordermsg)
{
MyOrder po = (MyOrder)ordermsg.Body;
Console.WriteLine("Processing id:{0}, name:{1} ", po.ID, po.Name);
}
public static void Main()
{
//init queue
if (!MessageQueue.Exists(Constants.QUEUE_PATH)) MessageQueue.Create(Constants.QUEUE_PATH, true);
//init wcf host via code
Uri baseUri = new Uri("http://localhost:7878/msmqsvc");
using (ServiceHost host = new ServiceHost(typeof(OrderProcessorService),baseUri))
{
//add metadata behavior
ServiceMetadataBehavior smb = new ServiceMetadataBehavior(){ HttpGetEnabled=true};
host.Description.Behaviors.Add(smb);
//add service endpoint
MsmqIntegrationBinding binding = new MsmqIntegrationBinding(MsmqIntegrationSecurityMode.None);
binding.SerializationFormat = MsmqMessageSerializationFormat.Binary;
host.AddServiceEndpoint(typeof(ClassLib.IOrderProcessor), binding, "msmq.formatname:DIRECT=OS:" + Constants.QUEUE_PATH);
host.Open();
// The service can now be accessed.
Console.WriteLine("The service is ready.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.ReadLine();
host.Close();
}
}
}
接口合同:
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
[ServiceKnownType(typeof(MyOrder))]
public interface IOrderProcessor
{
[OperationContract(IsOneWay = true, Action = "*")]
void SubmitPurchaseOrderInMessage(MsmqMessage<MyOrder> msg);
}
數組Parameters可以是客戶端可以傳遞的任何動態可序列化類型。 我認為問題在於此參數。 如果我在客戶端中刪除了此參數和可序列化的屬性以及binding.SerializationFormat,那么eveything可以正常工作。
可序列化的類:
[DataContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
[Serializable]
public class MyOrder
{
[DataMember]
public string ID;
[DataMember]
public string Name;
[DataMember]
public object[] Parameters;
}
[Serializable]
public class Transaction
{
public int Amount { get; set; }
}
客戶:
class Program
{
static void Main(string[] args)
{
try
{
Run();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
static void Run()
{
MsmqIntegrationBinding binding = new MsmqIntegrationBinding();
binding.Security.Mode = MsmqIntegrationSecurityMode.None;
binding.Security.Transport.MsmqAuthenticationMode = MsmqAuthenticationMode.None;
binding.Security.Transport.MsmqProtectionLevel = System.Net.Security.ProtectionLevel.None;
binding.SerializationFormat = MsmqMessageSerializationFormat.Binary;
EndpointAddress address = new EndpointAddress("msmq.formatname:DIRECT=OS:" + Constants.QUEUE_PATH);
ChannelFactory<ClassLib.IOrderProcessor> channelFactory = new ChannelFactory<ClassLib.IOrderProcessor>(binding, address);
try
{
ClassLib.IOrderProcessor channel = channelFactory.CreateChannel();
MyOrder order = new MyOrder();
order.ID = DateTime.Now.Ticks.ToString();
order.Name = "Order_" + order.ID;
order.Parameters = new object[] { new Transaction { Amount = 108 }, new Transaction { Amount = 100 } };
MsmqMessage<MyOrder> ordermsg = new MsmqMessage<MyOrder>(order);
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
channel.SubmitPurchaseOrderInMessage(ordermsg);
scope.Complete();
}
Console.WriteLine("Order has been submitted:{0}", ordermsg);
}
catch(Exception ex)
{
}
finally
{
channelFactory.Close();
}
}
}
這里有一些要檢查的東西:
在臨時出站隊列客戶端中不檢查任何消息。 如果此隊列中有消息,則表明該消息無法在網絡上傳輸。 因為您的隊列是事務性的,這可能意味着MSDTC配置 (鏈接也支持2012)。
在服務端檢查事務性死信隊列中是否沒有消息。 如果存在,則表示將消息傳遞到服務隊列時出現問題。 可能是權限問題。 服務帳戶在其隊列上需要“ 接收消息”和“ 查看消息 ”,客戶端帳戶在目標隊列上需要“ 發送消息” ,“ 獲取權限 ”和“ 獲取屬性 ”。
在Windows事件日志中啟用msmq日志記錄 。 這會將所有與MSMQ相關的活動記錄在框中。 服務端成功傳輸后,您應該在日志中看到2個事件: 消息來自網絡 ,並且ID為ID的消息進入隊列 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.