zoukankan      html  css  js  c++  java
  • Winfrom 使用WCF 实现双工通讯

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

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

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

    整个解决方案的结构

    1、通信接口的定义;

    服务端调用客户端接口IServerCallClient

    1. /// <summary>  
    2. /// 服务器调用客户端接口  
    3. /// </summary>  
    4. public interface IServerCallClient  
    5. {  
    6.     /// <summary>  
    7.     /// 服务器读取客户端的IP  
    8.     /// </summary>  
    9.     /// <returns></returns>  
    10.     [OperationContract]  
    11.     IPEndPoint ServerRequestCLientIP();  
    12.     /// <summary>  
    13.     /// 服务器发送消息给客户端  
    14.     /// </summary>  
    15.     /// <param name="text"></param>  
    16.     [OperationContract]  
    17.     void ServerSayMSG(string text);  
    18. }  
        /// <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

    1. <span style="font-weight: normal;">    [ServiceContract(CallbackContract =typeof(IServerCallClient))]//指定回调的接口  
    2.     public interface IClientCallServer  
    3.     {  
    4.         /// <summary>  
    5.         /// 客户端发送消息给服务器  
    6.         /// </summary>  
    7.         /// <param name="text"></param>  
    8.         [OperationContract]//指定操作约束,不添加该接口方法不可使用  
    9.         void ClientSayToServer(string text);  
    10.         /// <summary>  
    11.         /// 客户端读取服务端时间  
    12.         /// </summary>  
    13.         /// <returns></returns>  
    14.         [OperationContract]  
    15.         DateTime ClientRequestTime();  
    16.     }</span>  
    <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、被调用接口的实现

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

    1. class ServerCallClient :IServerCallClient  
    2. {  
    3.     public IPEndPoint ServerRequestCLientIP()  
    4.     {  
    5.         var ip =new IPEndPoint(IPAddress.Any,10086);  
    6.         return ip;  
    7.     }  
    8.     public void ServerSayMSG(string text)  
    9.     {  
    10.         File.AppendAllText("收到的数据", text);  
    11.     }  
    12. }  
        class ServerCallClient :IServerCallClient
        {
            public IPEndPoint ServerRequestCLientIP()
            {
                var ip =new IPEndPoint(IPAddress.Any,10086);
                return ip;
            }
            public void ServerSayMSG(string text)
            {
                File.AppendAllText("收到的数据", text);
            }
        }

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

    1. /// <summary>  
    2. /// 客户回调服务器类  
    3. /// </summary>  
    4. [ServiceBehavior(InstanceContextMode =InstanceContextMode.Single)]//通道只建立一个除非断开才新建(SessionID是同一个)  
    5. public class ClientCallServer : IClientCallServer, IDisposable  
    6. {  
    7.     public static List<IServerCallClient> ServerCallClientList { get; set; }=new List<IServerCallClient>();  
    8.     /// <summary>  
    9.     /// 返回服务器时间  
    10.     /// </summary>  
    11.     /// <returns></returns>  
    12.     public DateTime ClientRequestTime()  
    13.     {  
    14.         return DateTime.Now;  
    15.     }  
    16.     /// <summary>  
    17.     /// 客户端列表  
    18.     /// </summary>  
    19.     /// <summary>  
    20.     /// 服务端向客户端发数据  
    21.     /// </summary>  
    22.     /// <param name="text"></param>  
    23.     public void ClientSayToServer(string text)  
    24.     {  
    25.         var info = OperationContext.Current;  
    26.         File.AppendAllText("receive.txt",info.SessionId+text);//收到的数据存在文件  
    27.     }  
    28.     public void Dispose()  
    29.     {  
    30.         ServerCallClientList.Clear();  
    31.     }  
    32.     #endregion  
    33. }  
        /// <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、双工通道的建立

    服务端通道的建立
    1. ServiceHost serviceHost = new ServiceHost(typeof(ClientCallServer));//<span style="font-family: Arial, Helvetica, sans-serif;">指定回调的类</span>  
    2. serviceHost.AddServiceEndpoint(typeof(IClientCallServer),new WSDualHttpBinding(), "http://localhost:12345");//指定客户端的接口,通讯格式,服务器的地址  
    3. serviceHost.BeginOpen(callback=>  
    4. {  
    5.     serviceHost.EndOpen(callback);  
    6.     textBox1.Invoke(new Action(delegate {//不解释也能看得懂吧  
    7.         textBox1.AppendText("服务开启" + Environment.NewLine);  
    8.     }));  
    9. },null);  
                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);
    客户端通道的建立
    1. var rand = new Random();   
    2.  InstanceContext context = new InstanceContext(new ServerCallClient());//指定回调的类   
    3.  WSDualHttpBinding binding = new WSDualHttpBinding() { ClientBaseAddress = new Uri($"http://localhost:{rand.Next(10000, 20000)}") };//指定客户端地址;   
    4.  using (DuplexChannelFactory proxy = new DuplexChannelFactory(context, binding))//创建通道管理器  
    5.  {  
    6.   IClientCallServer client = proxy.CreateChannel(new EndpointAddress("http://localhost:12345"));// 创建用于将消息发送到特定终结点地址的服务的通道client.ClientRequestTime();   
    7.   client.ClientSayToServer("尼玛");   
    8.  }  
  • 相关阅读:
    OK335xS-Android mkmmc-android-ubifs.sh hacking
    OK335xS-Android pack-ubi-256M.sh hacking
    OK335xS Ubuntu 12.04.1 版本 Android 开发环境搭建
    Qt Quick Hello World hacking
    Qt QML referenceexamples attached Demo hacking
    QT 5.4.1 for Android Ubuntu QtWebView Demo
    I.MX6 working note for high efficiency
    QT 5.4.1 for Android Windows环境搭建
    mkbootimg hacking
    Generate And Play A Tone In Android hacking
  • 原文地址:https://www.cnblogs.com/yelanggu/p/8311209.html
Copyright © 2011-2022 走看看