5 wcf雙工
阿新 • • 發佈:2018-12-24
clu none design local 構造 請求 利用 username time
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))] publicILoginServiceinterface ILoginService { [OperationContract] void Login(string username); } //註意此處添加了回調接口 [ServiceContract] public interface ICallBack { [OperationContract] void Notify(string msg); } }
using System; using System.Collections.Generic;LoginServiceusing 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); } } } } } }
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等信息創建一個針對客戶端的管道,服務端就可以利用這個管道向服務端發送消息了
5 wcf雙工