一直以为感觉双工没弄懂,着实觉得很惆怅,在网上了解下双工的一些特点,直接上代码,以便以后项目中用的着:
service层:
class="brush:csharp;gutter:true;">定义一个IDuplexHello服务接口
[ServiceContract( Name = "DuplexHello", Namespace = "http://microsoft.wcf.documentation", CallbackContract = typeof(IHelloCallbackContract), //设置回调服务类型 SessionMode = SessionMode.Required )] public interface IDuplexHello { [OperationContract] void Hello(string greeting); }
实现DuplexHello.cs public class DuplexHello : IDuplexHello { public void Hello(string greeting) { Console.WriteLine("Caller sent: " + greeting); Console.WriteLine("Session ID: " + OperationContext.Current.SessionId); Console.WriteLine("Waiting two seconds before returning call."); Thread.Sleep(2000); var callerProxy = OperationContext.Current.GetCallbackChannel<IHelloCallbackContract>(); var response = "Service object " + this.GetHashCode().ToString() + " received: " + greeting; Console.WriteLine("Sending back: " + response); callerProxy.Reply(response); } }
定义回调接口(回调服务函数没有必要添加servicecontract,因为人家是包含在IDuplexHello服务类型中的)
public interface IHelloCallbackContract { [OperationContract(IsOneWay = true)] //一定要记得添加operationcontract void Reply(string responseToGreeting); }
这里的回调接口实现类(HelloCallbackContract.cs)我是直接在service层实现的,当然在项目里面肯能大多数情况下都是在客服端实现,我这里也就为了方便啦 public class HelloCallbackContract : IHelloCallbackContract { public void Reply(string responseToGreeting) { Console.WriteLine(responseToGreeting); } }
将service寄宿到控制台应用程序中(用的都是代码实现):
private static void Main(string[] args) { using (var host = new ServiceHost(typeof (DuplexHello), new Uri("http://localhost:991/DuplexHello"))) //添加基地址,在client就是这个地址,另外端口号不能鱼双工端口号相同 { host.AddServiceEndpoint(typeof (IDuplexHello), new NetTcpBinding(), "net.tcp://localhost:999/DuplexHello"); var metadatbehavior = host.Description.Behaviors.Find<ServiceMetadataBehavior>(); if (metadatbehavior == null) { metadatbehavior = new ServiceMetadataBehavior() { HttpGetEnabled = true }; host.Description.Behaviors.Add(metadatbehavior); } host.Opened += delegate { Console.WriteLine("服务已经启动"); }; host.Open(); Console.Read(); }
client层使用的也是一个控制台应用程序:
首先要运行宿主(找到host层资源文件夹bin->debug :host.exe)在更新wcf服务的时候也必须要先运行host.exe,否则会出现无法连接到服务器错误,
然后添加服务引用中地址栏输入http://localhost:991/DuplexHello 应用服务
再后应用之后客户端app.config自动生成如下代码:
<configuration> <system.serviceModel> <bindings> <netTcpBinding> <binding name="NetTcpBinding_DuplexHello" /> </netTcpBinding> </bindings> <client> <endpoint address="net.tcp://localhost:999/DuplexHello" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_DuplexHello" contract="ServiceReference1.DuplexHello" name="NetTcpBinding_DuplexHello"> <identity> <userPrincipalName value="objectboy-PC\objectboy" /> </identity> </endpoint> </client> </system.serviceModel> </configuration>
客服端控制台应用程序中代码:
private static void Main(string[] args) { var hellocallbackcontract = new HelloCallbackContract(); var instanceContext = new InstanceContext(hellocallbackcontract); //实例化客服端类服务上下文 var duplexChannelFactory = new DuplexChannelFactory<IDuplexHello>(instanceContext, new NetTcpBinding()); //实例化双工通道,并绑定为tcp通信,注意不能用ChannelFactory,因为这是双工 var endpointaddress = new EndpointAddress("net.tcp://localhost:999/DuplexHello"); var proxy = duplexChannelFactory.CreateChannel(endpointaddress); //创建并将消息发送到指定的消息通道 using (proxy as IDisposable) { proxy.Hello("cccccccccccccccccc"); } Console.Read(); }
客服端输出:
服务端输出: