简体   繁体   English

WCF不处理二进制格式的MSMQ消息

[英]WCF not processing MSMQ message with binary format

I have a WCF Windows Service that retrieve MSMQ messages. 我有一个WCF Windows服务,可以检索MSMQ消息。 The SubmitPurchaseOrderInMessage doesn't seem to get called neither do I see any messages in the queue. 似乎未调用SubmitPurchaseOrderInMessage,在队列中也看不到任何消息。 Code is shown below. 代码如下所示。

WCF class: 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();
        }
    }
}

Interface Contract: 接口合同:

[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
[ServiceKnownType(typeof(MyOrder))]
public interface IOrderProcessor
{
    [OperationContract(IsOneWay = true, Action = "*")]
    void SubmitPurchaseOrderInMessage(MsmqMessage<MyOrder> msg);
}

The array Parameters can be any dynamic serializable type that can be passed by client. 数组Parameters可以是客户端可以传递的任何动态可序列化类型。 I think issue is with this parameter. 我认为问题在于此参数。 If I remove this parameter and the serializable attribute and also the binding.SerializationFormat in the client, then eveything works fine. 如果我在客户端中删除了此参数和可序列化的属性以及binding.SerializationFormat,那么eveything可以正常工作。

Serializable class: 可序列化的类:

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

Client : 客户:

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

Here are some things to check: 这里有一些要检查的东西:

  1. Check no messages in temporary outbound queue client-side. 在临时出站队列客户端中不检查任何消息。 If there are messages in this queue it indicates that message cannot be transmitted across the network. 如果此队列中有消息,则表明该消息无法在网络上传输。 Because your queues are transactional this could mean MSDTC configuration (link supports 2012 also). 因为您的队列是事务性的,这可能意味着MSDTC配置 (链接也支持2012)。

  2. Check no messages in transactional dead letter queue on service-side. 在服务端检查事务性死信队列中是否没有消息。 If there are, this indicates a problem delivering the message to the service queue. 如果存在,则表示将消息传递到服务队列时出现问题。 Likely permissions issue. 可能是权限问题。 Service account requires Receive Message and Peek Message on it's queue, client account requires Send Message , Get Permissions , and Get Properties on destination queue. 服务帐户在其队列上需要“ 接收消息”和“ 查看消息 ”,客户端帐户在目标队列上需要“ 发送消息” ,“ 获取权限 ”和“ 获取属性 ”。

  3. Enable msmq logging in windows event log . 在Windows事件日志中启用msmq日志记录 This logs all MSMQ related activity on the box. 这会将所有与MSMQ相关的活动记录在框中。 Service-side for a successful transmission you should see 2 events in the log: Message came over network , and Message with ID was put into queue . 服务端成功传输后,您应该在日志中看到2个事件: 消息来自网络 ,并且ID为ID的消息进入队列

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM