Winfrom 使用WCF 实现双工通讯

来源:互联网 发布:微商的发展前景数据 编辑:程序博客网 时间:2024/05/17 21:47

实现双工通讯主要分三步。

  1. 通信接口的定义;
  2. 被调用接口的实现
  3. 双工通道的建立

请先引用DLL(CSDN的代码编辑器真尼玛蛋疼)


整个解决方案的结构


1、通信接口的定义;

服务端调用客户端接口IServerCallClient

    /// <summary>    /// 服务器调用客户端接口    /// </summary>    public interface IServerCallClient    {        /// <summary>        /// 服务器读取客户端的IP        /// </summary>        /// <returns></returns>        [OperationContract]        IPEndPoint ServerRequestCLientIP();        /// <summary>        /// 服务器发送消息给客户端        /// </summary>        /// <param name="text"></param>        [OperationContract]        void ServerSayMSG(string text);    }

客户端调用服务端接口IClientCallServer

<span style="font-weight: normal;">    [ServiceContract(CallbackContract =typeof(IServerCallClient))]//指定回调的接口    public interface IClientCallServer    {        /// <summary>        /// 客户端发送消息给服务器        /// </summary>        /// <param name="text"></param>        [OperationContract]//指定操作约束,不添加该接口方法不可使用        void ClientSayToServer(string text);        /// <summary>        /// 客户端读取服务端时间        /// </summary>        /// <returns></returns>        [OperationContract]        DateTime ClientRequestTime();    }</span>

上面的两个接口是单独的一个项目。

双方谈好了就好互相实现对方的方法。

2、被调用接口的实现

客户端实现服务端接口的类:

    class ServerCallClient :IServerCallClient    {        public IPEndPoint ServerRequestCLientIP()        {            var ip =new IPEndPoint(IPAddress.Any,10086);            return ip;        }        public void ServerSayMSG(string text)        {            File.AppendAllText("收到的数据", text);        }    }

服务端实现客户端接口的类

    /// <summary>    /// 客户回调服务器类    /// </summary>    [ServiceBehavior(InstanceContextMode =InstanceContextMode.Single)]//通道只建立一个除非断开才新建(SessionID是同一个)    public class ClientCallServer : IClientCallServer, IDisposable    {        public static List<IServerCallClient> ServerCallClientList { get; set; }=new List<IServerCallClient>();        /// <summary>        /// 返回服务器时间        /// </summary>        /// <returns></returns>        public DateTime ClientRequestTime()        {            return DateTime.Now;        }        /// <summary>        /// 客户端列表        /// </summary>        /// <summary>        /// 服务端向客户端发数据        /// </summary>        /// <param name="text"></param>        public void ClientSayToServer(string text)        {            var info = OperationContext.Current;            File.AppendAllText("receive.txt",info.SessionId+text);//收到的数据存在文件        }        public void Dispose()        {            ServerCallClientList.Clear();        }        #endregion    }

3、双工通道的建立

服务端通道的建立
            ServiceHost serviceHost = new ServiceHost(typeof(ClientCallServer));//<span style="font-family: Arial, Helvetica, sans-serif;">指定回调的类</span>            serviceHost.AddServiceEndpoint(typeof(IClientCallServer),new WSDualHttpBinding(), "http://localhost:12345");//指定客户端的接口,通讯格式,服务器的地址            serviceHost.BeginOpen(callback=>            {                serviceHost.EndOpen(callback);                textBox1.Invoke(new Action(delegate {//不解释也能看得懂吧                    textBox1.AppendText("服务开启" + Environment.NewLine);                }));            },null);

客户端通道的建立
var rand = new Random();  InstanceContext context = new InstanceContext(new ServerCallClient());//指定回调的类  WSDualHttpBinding binding = new WSDualHttpBinding() { ClientBaseAddress = new Uri($"http://localhost:{rand.Next(10000, 20000)}") };//指定客户端地址;  using (DuplexChannelFactory proxy = new DuplexChannelFactory(context, binding))//创建通道管理器 {  IClientCallServer client = proxy.CreateChannel(new EndpointAddress("http://localhost:12345"));// 创建用于将消息发送到特定终结点地址的服务的通道client.ClientRequestTime();   client.ClientSayToServer("尼玛");  }


0 0
原创粉丝点击