WCF 学习笔记(三)构建双向通讯(tcp/http)

在本次记录中将记录一下如果创建一个基于nettcp 或http 下的双向通讯的WCF。
tcp 下的双向通讯:
由于使用tcp的方式,会遵循tcp 的方式,即和HOstServer端先创建一个连接,然后,所有的命令都会在这个connection上进行传输,当然如果是CallBack的部分的数据也会在同一个Connection中进行传输。下面就看下如何创建一个简单的Duplex 。
以下修改 学习笔记中(1)中的程序来实现。 工程架构如下:


1.修改MyData命名空间的类。如下:
 1using System;
 2using System.Collections.Generic;
 3using System.Text;
 4using System.ServiceModel;
 5
 6
 7namespace TESTWCF.MyData
 8{
 9    [ServiceContract(Namespace = "http://www.cnblogs.net/zhucl1006", CallbackContract = typeof(ICallBack))]
10    public interface IMyDataService
11    {
12        [OperationContract(IsOneWay = true)]
13        void GetServerTime(string userName);
14    }

15
16
17    [ServiceContract(Namespace = "http://www.cnblogs.net/zhucl1006")]
18    public interface ICallBack
19    {
20        [OperationContract(IsOneWay=true)]
21        void ServerReturn(string times);
22    }

23
24}

注意方法中使用的OperationContract中要使用IsOneWay=true , 否则在调用的时候, 返回callback 后Client端会被锁住。
至于OperationContract中的属性,我也了解很少,以后再补上详细的描述。
isOneWay=true 理解为:则表明客户端与服务端之间只有请求,没有响应。
HostServer端调整:
添加一个MyDataService的类,继承IMyDataService。如下:

using System;
using System.Collections.Generic;
using System.Text;
using TESTWCF.MyData;
using System.ServiceModel;

namespace TESTWCF.HostServer
{

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
    public class MyDataService : IMyDataService
    {
       
        #region IMyDataService 成员

        public void GetServerTime(string userName)
        {
            string str = System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            ICallBack callback = OperationContext.Current.GetCallbackChannel<ICallBack>();
            callback.ServerReturn(str);

        }
        #endregion
    }
}


在这里可以看到,在GetServerTime的方法中,使用OperationContext.Current.GetCallBAckChannel的方法获取当前连接的CallBack Contact。
然后调用该契约的方法,调用Client端的方法。
Clinet端修改:
app.config :
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
<system.serviceModel>
      
      
<client>
          
<endpoint address="net.tcp://localhost:8010/MyData" binding="netTcpBinding" bindingConfiguration="" 
                  contract
="TESTWCF.MyData.IMyDataService"  name="tcpendpoint" />
      
<!--<endpoint address="http://localhost:8090/MyData" binding="basicHttpBinding"
                contract="TESTWCF.MyData.IMyDataService" />
-->
    
</client>
  
</system.serviceModel>
</configuration>
窗体代码:
Code
运行后即可实现 在ServerReturn中得到返回值,并显示到窗体上。


Http 下的双向通讯:

在Http的协议下,由于http协议是 一个应用层的协议,它采用传统的Request/Reply的方式进行通信,所以,当要实现双向通讯的时候,需要在Client端也建立一个Server端,用来接收CallBack的数据。
在上面的例子中,可以通过修改app.config来实现http下的双向。
Server端的app.config 修改如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
<system.serviceModel>
    
<services>
      
<service name="TESTWCF.HostServer.MyDataService" behaviorConfiguration="serviceBehavior">
          
<endpoint binding="wsDualHttpBinding" contract="TESTWCF.MyData.IMyDataService" address="MyData" />
          
<endpoint binding="netTcpBinding" contract="TESTWCF.MyData.IMyDataService" address="MyData" />

          
<!--<endpoint binding="mexHttpBinding" contract="IMetadataExchange" address="mex" />-->
        
<host>
          
<baseAddresses>
            
<add baseAddress="http://localhost:8090"/>
              
<add baseAddress="net.tcp://localhost:8010"/>

          
</baseAddresses>
        
</host>
      
</service>
    
</services>

    
<behaviors>
      
<serviceBehaviors>
        
<behavior name="serviceBehavior">
          
<serviceMetadata httpGetEnabled="false" />
        
</behavior>
      
</serviceBehaviors>
    
</behaviors>
  
</system.serviceModel>
</configuration>
Client端appconfig修改如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
<system.serviceModel>
      
<bindings>
          
<wsDualHttpBinding>
              
<binding name="wsDualBinding_IMyData" clientBaseAddress="http://localhost:8888/myClient/" />
          
</wsDualHttpBinding>
      
</bindings>

      
<client>
          
<!--<endpoint address="net.tcp://localhost:8010/MyData" binding="netTcpBinding" bindingConfiguration="" 
                  contract="TESTWCF.MyData.IMyDataService"  name="tcpendpoint" />
-->
      
<endpoint address="http://localhost:8090/MyData" binding="wsDualHttpBinding" bindingConfiguration="wsDualBinding_IMyData"
                contract
="TESTWCF.MyData.IMyDataService"  name="tcpendpoint"/>
    
</client>
  
</system.serviceModel>
</configuration>


通过以上修改app.config , 就可以实现一个基于http模式下的wcf 的程序了。
个人觉得是用tcp的方式要比http的方式要好,因为tcp的方式,使用二进制的方式进行网络传输, 而http的方式使用文本的方式进行传输。tcp使用tcp的方式建立连接,保证数据不丢,而且tcp的方式是先建立一个连接,然后再该连接上进行操作  , 所以效能上也比http的方式要快。


源码下载




原文地址:https://www.cnblogs.com/zhucl1006/p/1043991.html