WCF Asynchronous Callback

I have successfully implemented the WCF callback template in my code, and now I want to implement an asynchronous callback. Here is my interface code:

[ServiceContract(Name = "IMessageCallback")] public interface IMessageCallback { [OperationContract(IsOneWay = true)] void OnMessageAdded(string message, DateTime timestamp); } [ServiceContract(Name="IMessageCallback")] public interface IAsyncMessageCallback { [OperationContract(AsyncPattern = true)] IAsyncResult BeginOnMessageAdded(string msg, DateTime timestamp, AsyncCallback callback, object asyncState); void EndOnMessageAdded(IAsyncResult result); } [ServiceContract(CallbackContract = typeof(IMessageCallback))] public interface IMessage { [OperationContract] void AddMessage(string message); } 

To use a synchronous callback, I declared my channel and endpoint as follows:

 DuplexChannelFactory<IMessage> dcf = new DuplexChannelFactory<IMessage>(new InstanceContext(this), "WSDualHttpBinding_IMessage"); <endpoint address="net.tcp://localhost:8731/Message/" binding="netTcpBinding" contract="WCFCallbacks.IMessage" name="WSDualHttpBinding_IMessage"> 

I'm having trouble getting the right combination of endpoint and channel to use asynchronous callback. Can someone point me in the right direction?

In addition, if the following line of code is executed:

 OperationContext.Current.GetCallbackChannel<IAsyncMessageCallback>(); 

I get the following error:

 Unable to cast transparent proxy to type 'WCFCallbacks.IAsyncMessageCallback' 
+6
source share
1 answer

You need to change the CallbackContract property of the IMessage service contract to this type (IAsyncMessageCallback). The example below runs with an asynchronous callback.

  public class StackOverflow_5979252 { [ServiceContract(Name = "IMessageCallback")] public interface IAsyncMessageCallback { [OperationContract(AsyncPattern = true)] IAsyncResult BeginOnMessageAdded(string msg, DateTime timestamp, AsyncCallback callback, object asyncState); void EndOnMessageAdded(IAsyncResult result); } [ServiceContract(CallbackContract = typeof(IAsyncMessageCallback))] public interface IMessage { [OperationContract] void AddMessage(string message); } [ServiceBehavior(IncludeExceptionDetailInFaults = true, ConcurrencyMode = ConcurrencyMode.Multiple)] public class Service : IMessage { public void AddMessage(string message) { IAsyncMessageCallback callback = OperationContext.Current.GetCallbackChannel<IAsyncMessageCallback>(); callback.BeginOnMessageAdded(message, DateTime.Now, delegate(IAsyncResult ar) { callback.EndOnMessageAdded(ar); }, null); } } class MyClientCallback : IAsyncMessageCallback { public IAsyncResult BeginOnMessageAdded(string msg, DateTime timestamp, AsyncCallback callback, object asyncState) { Action<string, DateTime> act = (txt, time) => { Console.WriteLine("[{0}] {1}", time, txt); }; return act.BeginInvoke(msg, timestamp, callback, asyncState); } public void EndOnMessageAdded(IAsyncResult result) { Action<string,DateTime> act = (Action<string,DateTime>)((System.Runtime.Remoting.Messaging.AsyncResult)result).AsyncDelegate; act.EndInvoke(result); } } static Binding GetBinding() { return new NetTcpBinding(SecurityMode.None); } public static void Test() { string baseAddress = "net.tcp://" + Environment.MachineName + ":8000/Service"; ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress)); host.AddServiceEndpoint(typeof(IMessage), GetBinding(), ""); host.Open(); Console.WriteLine("Host opened"); InstanceContext instanceContext = new InstanceContext(new MyClientCallback()); DuplexChannelFactory<IMessage> factory = new DuplexChannelFactory<IMessage>(instanceContext, GetBinding(), new EndpointAddress(baseAddress)); IMessage proxy = factory.CreateChannel(); proxy.AddMessage("Hello world"); Console.Write("Press ENTER to close the host"); Console.ReadLine(); ((IClientChannel)proxy).Close(); factory.Close(); host.Close(); } } 
+10
source

Source: https://habr.com/ru/post/887931/


All Articles