2013-04-02 2 views
5

In einem normal WCF Request/Reply-Vertrag, können Sie die Nachrichten-Header mit so etwas wie lesen:So lesen Sie WCF-Nachrichtenkopfzeilen im Duplex-Callback?

OperationContract.Current.IncomingMessageHeaders 

Was ich nicht herausfinden kann, wie dies von einem Duplex-Vertrag auf der Callback-Seite zu tun. Innerhalb der Callback-Implementierung ist OperationContext.Currentnull.

Bearbeiten 4/5/2013: Ich verwende eine benutzerdefinierte Bindung basierend auf net.tcp, aber mit vielen Anpassungen. Beispielsweise verwendet die Protokollpuffer-Nachrichtencodierung statt Xml. Auch gibt es einige benutzerdefinierte Sicherheit.

Antwort

3

Welche Bindung verwenden Sie? In der folgenden SSCCE ist der Kontext für die Callback-Implementierung nicht null.

public class StackOverflow_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(); 
    } 
} 
+0

Danke für das extrem vollständige Beispiel. Ich benutze eine benutzerdefinierte Bindung mit Protokoll-Puffer-Nachrichten-Codierung, einige benutzerdefinierte Sicherheit und ein paar andere Dinge, die ich nicht von meinem Kopf erinnere (ich schaue heute). Könnte das den OperationContext beeinflussen? –