如何在双工回调中读取 WCF 消息头?

Posted

技术标签:

【中文标题】如何在双工回调中读取 WCF 消息头?【英文标题】:How to read WCF message headers in duplex callback? 【发布时间】:2013-03-24 01:52:55 【问题描述】:

在正常的 WCF 请求/回复合同中,您可以使用以下方式读取消息标头:

OperationContract.Current.IncomingMessageHeaders

我不知道如何在双工合约的回调端执行此操作。回调实现内部OperationContext.Currentnull

2013 年 4 月 5 日编辑: 我正在使用基于 net.tcp 的自定义绑定,但有很多自定义项。例如,使用协议缓冲区消息编码而不是 Xml。还有一些自定义安全性。

【问题讨论】:

【参考方案1】:

您使用的是什么绑定?在 SSCCE 下面的回调实现中上下文不为空。

public class ***_15769719

    [ServiceContract(CallbackContract = typeof(ICallback))]
    public interface ITest
    
        [OperationContract]
        string Hello(string text);
    
    [ServiceContract]
    public interface ICallback
    
        [OperationContract(IsOneWay = true)]
        void OnHello(string text);
    
    public class Service : ITest
    
        public string Hello(string text)
        
            ICallback callback = OperationContext.Current.GetCallbackChannel<ICallback>();
            ThreadPool.QueueUserWorkItem(delegate
            
                callback.OnHello(text);
            );

            return text;
        
    
    class MyCallback : ICallback
    
        AutoResetEvent evt;
        public MyCallback(AutoResetEvent evt)
        
            this.evt = evt;
        

        public void OnHello(string text)
        
            Console.WriteLine("[callback] Headers: ");
            foreach (var header in OperationContext.Current.IncomingMessageHeaders)
            
                Console.WriteLine("[callback]   0", header);
            

            Console.WriteLine("[callback] OnHello(0)", text);
            evt.Set();
        
    
    public static void Test()
    
        bool useTcp = false;
        string baseAddress = useTcp ? 
            "net.tcp://" + Environment.MachineName + ":8000/Service" :
            "http://" + Environment.MachineName + ":8000/Service";
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
        Binding binding = useTcp ?
            (Binding)new NetTcpBinding(SecurityMode.None) :
            new WSDualHttpBinding(WSDualHttpSecurityMode.None)
            
                ClientBaseAddress = new Uri("http://" + Environment.MachineName + ":8888/Client")
            ;
        host.AddServiceEndpoint(typeof(ITest), binding, "");
        host.Open();
        Console.WriteLine("Host opened");

        AutoResetEvent evt = new AutoResetEvent(false);
        MyCallback callback = new MyCallback(evt);
        DuplexChannelFactory<ITest> factory = new DuplexChannelFactory<ITest>(
            new InstanceContext(callback),
            binding,
            new EndpointAddress(baseAddress));
        ITest proxy = factory.CreateChannel();

        Console.WriteLine(proxy.Hello("foo bar"));
        evt.WaitOne();

        ((IClientChannel)proxy).Close();
        factory.Close();

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();
        host.Close();
    

【讨论】:

感谢非常完整的示例。我正在使用带有协议缓冲区消息编码的自定义绑定,一些自定义安全性和其他一些我不记得的事情(我今天会看看)。这会影响 OperationContext 吗?

以上是关于如何在双工回调中读取 WCF 消息头?的主要内容,如果未能解决你的问题,请参考以下文章

防止 WCF 双工回调服务出现死锁问题

WCF 回调中收到的消息有问题

如何根据消息头属性仅读取特定队列消息

通过消息头的 WCF 安全性

将自定义消息头添加到从 Windows Mobile 6 客户端使用的 WCF 服务

[老老实实学WCF] 第十篇 消息通信模式(下) 双工