zoukankan      html  css  js  c++  java
  • 5 wcf双工

    1 创建两个项目

    Wcf_WsDual_Service   Wcf_WsDual_Client

    2 Wcf_WsDual_Service   项目中创建 LoginService.cs 的wcf文件

    using System.ServiceModel;
    
    namespace Wcf_WsDual_Service
    {
        // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“ILogin”。
        //注意此处构造函数里面的回调
        [ServiceContract(CallbackContract =typeof(ICallBack))]
        public interface ILoginService
        {
            [OperationContract]
            void Login(string username);
        }
        //注意此处添加了回调接口
        [ServiceContract]
        public interface ICallBack
        {
            [OperationContract]
            void Notify(string msg);
        }
    }
    ILoginService
    using System;
    using System.Collections.Generic;
    using System.ServiceModel;
    
    namespace Wcf_WsDual_Service
    {
        // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的类名“Login”。
        public class LoginService : ILoginService
        {
            //存储所有请求了这个服务的客户端管道
            public static Dictionary<string, ICallBack> channelDic = new Dictionary<string, ICallBack>();
            void ILoginService.Login(string username)
            {
                //获得请求带ICallBack的endpoint的channel
                var callback = OperationContext.Current.GetCallbackChannel<ICallBack>();
                channelDic[username] = callback;
                Console.WriteLine($"用户{username}已经登录");
            }
            //服务端动作
            public static void OperateAction()
            {
                while (true)
                {
                    string msg = Console.ReadLine();
                    if (!string.IsNullOrEmpty(msg))
                    {
                        //遍历客户端管道 向这些管道发送消息
                        foreach (var item in channelDic)
                        {
                            item.Value.Notify(msg);
                        }
    
                    }
    
                }
            }
        }
    }
    LoginService

    3 修改服务配置文件

       a 将协议改成双工  b将对应双工的安全设置成无安全      

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <startup> 
            <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
        </startup>
        <system.serviceModel>
    
         <!--双工默认有安全验证 这里取消安全-->
          <bindings>
            <wsDualHttpBinding>
              <binding name="MyDual">
                <security mode="None"></security>
              </binding>
            </wsDualHttpBinding>
          </bindings>
          
            <behaviors>
                <serviceBehaviors>
                    <behavior name="">
                        <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                        <serviceDebug includeExceptionDetailInFaults="false" />
                    </behavior>
                </serviceBehaviors>
            </behaviors>
            <services>
                <service name="Wcf_WsDual_Service.LoginService">
                    <endpoint address="" binding="wsDualHttpBinding" bindingConfiguration="MyDual"
                        contract="Wcf_WsDual_Service.ILoginService">
                        <identity>
                            <dns value="localhost" />
                        </identity>
                    </endpoint>
                    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
                    <host>
                        <baseAddresses>
                            <add baseAddress="http://localhost:8988/Design_Time_Addresses/Wcf_WsDual_Service/Login/" />
                        </baseAddresses>
                    </host>
                </service>
            </services>
        </system.serviceModel>
    </configuration>
    appConfig

     4.在服务端main方法中启动服务,并异步启动线程用以向客户端发送消息

    using System;
    using System.ServiceModel;
    using System.Threading.Tasks;
    
    namespace Wcf_WsDual_Service
    {
        class Program
        {
            static void Main(string[] args)
            {
                ServiceHost host = new ServiceHost(typeof(LoginService));
                host.Open();
                Console.WriteLine("服务已经启动");
                Task.Run(() =>
                {
                    LoginService.OperateAction();
                });
    
                System.Threading.Thread.Sleep(int.MaxValue);
            }
           
        }
        
    }
    Program

    5.客户端引用服务引用

    6.客户端创建一个LoginCallBack类实现服务端定义的iLoginCallBack接口

      public class LoginCallBack : ILoginServiceCallback
        {
            public void Notify(string msg)
            {
                Console.WriteLine(msg);
            }
        }
    LoginCallBack

    7.客户端main方法创建一个服务实例,并想服务发送请求,在服务端这个请求会记录下这个请求对应的客户端的信息

     class Program
        {
            static void Main(string[] args)
            {
                var instanceContext = new InstanceContext(new LoginCallBack());
                LoginServiceClient client = new LoginServiceClient(instanceContext);
                client.Login("winner");
                Console.ReadKey();
            }
        }
    客户端Program

    8.这样启动服务之后,再启动客户端,客户端会给服务端发送一个请求,服务端会记录下客户端的endpoint等信息创建一个针对客户端的管道,服务端就可以利用这个管道向服务端发送消息了

  • 相关阅读:
    视频笔记
    【LeetCode】给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度
    getopt函数用法
    一些常用的算法库
    c语言结构体
    C语言中time_t数据类型详细介绍
    c语言 static的用法
    C语言中extern的用法
    MATLAB textread函数
    正则表达式
  • 原文地址:https://www.cnblogs.com/wholeworld/p/10165941.html
Copyright © 2011-2022 走看看