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等信息创建一个针对客户端的管道,服务端就可以利用这个管道向服务端发送消息了

原文地址:https://www.cnblogs.com/wholeworld/p/10165941.html

时间: 2024-10-12 01:42:24

5 wcf双工的相关文章

Wcf 双工通信的应用

概述 双工(Duplex)模式的消息交换方式体现在消息交换过程中,参与的双方均可以向对方发送消息.基于双工MEP消息交换可以看成是多个基本模式下(比如请求-回复模式和单项模式)消息交换的组合.双工MEP又具有一些变体,比如典型的订阅-发布模式就可以看成是双工模式的一种表现形式.双工消息交换模式使服务端回调(Callback)客户端操作成为可能. 在Wcf中不是所有的绑定协议都支持回调操作,BasicHttpBinding,WSHttpBinding绑定协议不支持回调操作:NetTcpBindin

wcf双工通信

一直以为感觉双工没弄懂,着实觉得很惆怅,在网上了解下双工的一些特点,直接上代码,以便以后项目中用的着: service层: ? 1 定义一个IDuplexHello服务接口 ? 1 2 3 4 5 6 7 8 9 10 11 [ServiceContract(       Name = "DuplexHello",       Namespace = "http://microsoft.wcf.documentation",       CallbackContra

WCF双工模式

双工模式 描述:双工模式建立在答复模式和单向模式的基础之上,实现客户端与服务端相互的调用. 相互调用:以往我们只是在客户端调用服务端,然后服务端有返回值返回客户端,而相互调用不光是客户端调用服务端,而且服务端也可以调用客户端的方法. 1.添加WCF服务 Service2.svc,并定义好回调的接口,服务器端接口IService2.cs: using System; using System.Collections.Generic; using System.Linq; using System.

wcf 双工

服务器 [ServiceContract(Namespace="http://www.artech.com/", CallbackContract = typeof(ICallback))] 服务接口加入CallbackContract //添加回调接口,用户客户端回调的实现,客户端代理会自动生成这个接口. public interface ICallback { [OperationContract(IsOneWay=true)] void DisplayResult(double

wcf双工通讯遇到的问题

1.向ChannelFactory提供的InstanceContext包含未实现CallbackContractType的问题 通过添加服务引用生成的客户端代码, public class CallbackHandler : ICalculatorDuplexCallback 这里的接口必须是添加服务引用添加出来的,using Client.ServiceReference1; 2.“在消息传输完成以前关闭会话” 这个问题是在测试的时候发现的,我在测试代码里也写了注释.分析过后发现,原来我们将p

WCF系列之双工通信

WCF双工通信允许客户端调用服务器端,也允许通过回调,实现服务器端调用客户端,并不是所有的协议都支持双工通信,比如HTTP协议是不支持双工通信的. 我们来看一下契约的定义,其中在ServiceContract指定了CallbackContract,定义了ICalculateCallback,回调契约不需要指定为ServiceContract,但是方法要标记为OperationContract,可以看到服务契约和回调的方法均指定为IsOneWay=true,返回值都是void. 下一步,再来看一下

利用WCF的双工通讯实现一个简单的心跳监控系统 z

利用WCF的双工通讯实现一个简单的心跳监控系统 http://www.cnblogs.com/zuowj/p/5761011.html 何为心跳监控系统? 故名思义,就是监控某个或某些个程序的运行状态,就好比医院里面的心跳监视仪一样,能够随时显示病人的心跳情况. 心跳监控的目的是什么? 与医院里面的心跳监视仪目的类似,监控程序运行状态,一旦出现问题(比如:一些自动运行的服务.程序等突然停止运行了),那么心跳监控系统就能“感 知到”并及时的显示在监控界面上,同时可以通过微信.短信告之相关的人员,以

利用WCF的双工通讯实现一个简单的心跳监控系统

何为心跳监控系统? 故名思义,就是监控某个或某些个程序的运行状态,就好比医院里面的心跳监视仪一样,能够随时显示病人的心跳情况. 心跳监控的目的是什么? 与医院里面的心跳监视仪目的类似,监控程序运行状态,一旦出现问题(比如:一些自动运行的服务.程序等突然停止运行了),那么心跳监控系统就能“感知到”并及时的显示在监控界面上,同时可以通过微信.短信告之相关的人员,以便他们及时处理程序异常,从而避免一些自动运行的服务.程序等突然停止运行而造成的一系列损失 心跳监控系统实现的思路是怎样的? 核心技术:WC

Wcf双向通信

创建服务契约 [ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(ICallBack))] public interface IUser { [OperationContract] string GetName(string name); } 回调 public interface ICallBack { [OperationContract(IsOneWay=true)] void Pri