Winfrom 使用WCF 實現雙工通訊
阿新 • • 發佈:2019-01-24
實現雙工通訊主要分三步。
- 通訊介面的定義;
- 被呼叫介面的實現
- 雙工通道的建立
請先引用DLL(CSDN的程式碼編輯器真尼瑪蛋疼)
整個解決方案的結構
1、通訊介面的定義;
服務端呼叫客戶端介面IServerCallClient
/// <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
<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、被呼叫介面的實現
客戶端實現服務端介面的類:
class ServerCallClient :IServerCallClient { public IPEndPoint ServerRequestCLientIP() { var ip =new IPEndPoint(IPAddress.Any,10086); return ip; } public void ServerSayMSG(string text) { File.AppendAllText("收到的資料", text); } }
服務端實現客戶端介面的類
/// <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、雙工通道的建立
服務端通道的建立 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);
客戶端通道的建立
var rand = new Random();
InstanceContext context = new InstanceContext(new ServerCallClient());//指定回撥的類
WSDualHttpBinding binding = new WSDualHttpBinding() { ClientBaseAddress = new Uri($"http://localhost:{rand.Next(10000, 20000)}") };//指定客戶端地址;
using (DuplexChannelFactory proxy = new DuplexChannelFactory(context, binding))//建立通道管理器
{
IClientCallServer client = proxy.CreateChannel(new EndpointAddress("http://localhost:12345"));// 建立用於將訊息傳送到特定終結點地址的服務的通道client.ClientRequestTime();
client.ClientSayToServer("尼瑪");
}