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