首页 > 代码库 > wcf双工通信

wcf双工通信

一直以为感觉双工没弄懂,着实觉得很惆怅,在网上了解下双工的一些特点,直接上代码,以便以后项目中用的着:

service层:

?
1
定义一个IDuplexHello服务接口
?
1
2
3
4
5
6
7
8
9
10
11
[ServiceContract(
      Name = "DuplexHello",
      Namespace = "http://microsoft.wcf.documentation",
      CallbackContract = typeof(IHelloCallbackContract), //设置回调服务类型
      SessionMode = SessionMode.Required
    )]
    public interface IDuplexHello
    {
        [OperationContract]
        void Hello(string greeting);
    }
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
实现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);
        }
    }
?
1
定义回调接口(回调服务函数没有必要添加servicecontract,因为人家是包含在IDuplexHello服务类型中的)
?
1
2
3
4
5
public interface IHelloCallbackContract
    {
        [OperationContract(IsOneWay = true)]   //一定要记得添加operationcontract
        void Reply(string responseToGreeting);
    }
?
1
2
3
4
5
6
7
8
这里的回调接口实现类(HelloCallbackContract.cs)我是直接在service层实现的,当然在项目里面肯能大多数情况下都是在客服端实现,我这里也就为了方便啦
 public class HelloCallbackContract : IHelloCallbackContract
    {
        public void Reply(string responseToGreeting)
        {
            Console.WriteLine(responseToGreeting);
        }
    }

将service寄宿到控制台应用程序中(用的都是代码实现):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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自动生成如下代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<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=http://www.mamicode.com/"objectboy-PC\objectboy" />
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>
</configuration>

客服端控制台应用程序中代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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();
        }

 客服端输出:

服务端输出: