2014-06-30 73 views
1

我有一个检索MSMQ消息的WCF Windows服务。 SubmitPurchaseOrderInMessage似乎不会被调用,也不会看到队列中的任何消息。代码如下所示。WCF不处理二进制格式的MSMQ消息

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); 
} 

阵列的参数可以是可由客户机被传递的任何动态序列化类型。我认为问题在于这个参数。如果我删除这个参数和可序列化的属性以及客户端中的binding.SerializationFormat,那么eveything可以正常工作。

Serializable类:

[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(); 
     } 
    } 
} 
+0

http://msdn.microsoft.com/en-us/library/ms733025(v=vs.110).aspx –

回答

0

这里有一些事情要检查:临时出站队列客户端

  1. 检查没有消息。如果此队列中有消息,则表示该消息无法通过网络传输。因为你的队列是事务性的,这可能意味着MSDTC configuration(链接支持2012)。

  2. 检查服务端事务性的死信队列中没有消息。如果存在,则表示将消息传递到服务队列时出现问题。可能的权限问题。服务帐户需要接收消息皮克消息上的队列,客户帐户需要发送消息获取权限获取有关目标队列属性

  3. Enable msmq logging in windows event log。这将在该框中记录与MSMQ相关的所有活动。在成功传输的服务端,您应该在日志中看到2个事件:通过网络发送的消息带ID的消息已放入队列

+0

我得到的错误是“无法找到程序集‘WCFClientApp’”问题是通过将Transaction类移动到定义MyOrder的库来解决(暂时)。但是这并没有解决我的问题,因为参数(上面的字段)中的对象是从客户端(WCFClientApp程序集)传递的。 – arjun

+0

所以你的错误与MSMQ完全没有关系。 –

+0

是的。但是,您能否就上述问题提供一些想法(关于动态类型) – arjun