NetTcpBinding做双工回调与订阅/发布

一:回调代码:
WcfServiceLibrary2:
using System.ServiceModel; namespace WcfServiceLibrary2 { [ServiceContract(CallbackContract = typeof(ICallback))] public interface IService1 { [OperationContract(IsOneWay = true)] void GetData(string value); } public interface ICallback { [OperationContract(IsOneWay = true)] void DisplayResult(string result); } }
WcfClient:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.ServiceModel; using System.Text; using System.Windows.Forms; using WcfServiceLibrary2; namespace WcfClient { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { EndpointAddress address = new EndpointAddress("net.tcp://localhost:8773/MyTest"); NetTcpBinding binding = new NetTcpBinding(); DuplexChannelFactory<IService1> channelFactory = new DuplexChannelFactory<IService1>(new InstanceContext(new Back()), binding, address); var channel = channelFactory.CreateChannel(); channel.GetData("111"); } public class Back : ICallback { public void DisplayResult(string result) { MessageBox.Show(result); } } private void Form1_Load(object sender, EventArgs e) { this.Text = "客户端"; } } }
WcfServer:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | using System; using System.Collections.Generic; using System.Linq; using System.ServiceModel; using System.Text; using System.Windows.Forms; using WcfServiceLibrary2; namespace WcfServer { public class Service1 : IService1 { public void GetData(Guid id) { ICallback call = OperationContext.Current.GetCallbackChannel<ICallback>(); //call.DisplayResult("回调客户端---"+value); WcfServer.Form1 form = Application.OpenForms[0] as WcfServer.Form1; form.AddSubscriber(id, call); } } } |
using System; using System.ServiceModel; using System.Windows.Forms; namespace WcfServer { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { this.Text = "服务端"; ServiceHost host = new ServiceHost(typeof(WcfServer.Service1)); host.Open(); } private void button1_Click(object sender, EventArgs e) { } } }
appConfig:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services> <service name="WcfServer.Service1"> <!--<host> <baseAddresses> <add baseAddress = "http://localhost:8773/Design_Time_Addresses/WcfServiceLibrary2/Service1/" /> </baseAddresses> </host>--> <!-- Service Endpoints --> <!-- 除非完全限定,否则地址相对于上面提供的基址--> <endpoint address="net.tcp://localhost:8773/MyTest/" binding="netTcpBinding" contract="WcfServiceLibrary2.IService1"> <!-- 部署时,应移除或替换下列标识元素,以反映 用来运行所部署服务的标识。移除之后,WCF 将 自动推断相应标识。 --> <!--<identity> <dns value="localhost"/> </identity>--> </endpoint> <!-- Metadata Endpoints --> <!-- 元数据交换终结点供相应的服务用于向客户端做自我介绍。 --> <!-- 此终结点不使用安全绑定,应在部署前确保其安全或将其移除--> </service> </services> <!--<behaviors> <serviceBehaviors> <behavior> --><!-- 为避免泄漏元数据信息, 请在部署前将以下值设置为 false --><!-- <serviceMetadata httpGetEnabled="False"/> --><!-- 要接收故障异常详细信息以进行调试, 请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 --><!-- <serviceDebug includeExceptionDetailInFaults="False" /> </behavior> </serviceBehaviors> </behaviors>--> </system.serviceModel> </configuration>
二:发布、订阅(其余代码不变)
wcfServer:
using System; using System.Collections.Generic; using System.Linq; using System.ServiceModel; using System.Text; using System.Windows.Forms; using WcfServiceLibrary2; namespace WcfServer { public class Service1 : IService1 { public void GetData(Guid id) { ICallback call = OperationContext.Current.GetCallbackChannel<ICallback>(); //call.DisplayResult("回调客户端---"+value); WcfServer.Form1 form = Application.OpenForms[0] as WcfServer.Form1; form.AddSubscriber(id, call); } } }
using System; using System.Collections.Generic; using System.ServiceModel; using System.Windows.Forms; using WcfServiceLibrary2; namespace WcfServer { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { this.Text = "服务端"; ServiceHost host = new ServiceHost(typeof(Service1)); host.Open(); } Dictionary<Guid, ICallback> dic = new Dictionary<Guid, ICallback>(); public void AddSubscriber(Guid id, ICallback callback) { if (!dic.ContainsKey(id)) { dic.Add(id, callback); } } private void button1_Click(object sender, EventArgs e) { foreach (KeyValuePair<Guid, ICallback> pair in dic) { pair.Value.DisplayResult("1"); } } } }
Iservice1:
using System; using System.ServiceModel; namespace WcfServiceLibrary2 { [ServiceContract(CallbackContract = typeof(ICallback))] public interface IService1 { [OperationContract(IsOneWay = true)] void GetData(Guid value); } public interface ICallback { [OperationContract(IsOneWay = true)] void DisplayResult(string result); } }
WcfClient:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.ServiceModel; using System.Text; using System.Windows.Forms; using WcfServiceLibrary2; namespace WcfClient { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { EndpointAddress address = new EndpointAddress("net.tcp://localhost:8773/MyTest"); NetTcpBinding binding = new NetTcpBinding(); DuplexChannelFactory<IService1> channelFactory = new DuplexChannelFactory<IService1>(new InstanceContext(new Back()), binding, address); var channel = channelFactory.CreateChannel(); channel.GetData(new Guid()); } public class Back : ICallback { public void DisplayResult(string result) { MessageBox.Show(result); } } private void Form1_Load(object sender, EventArgs e) { this.Text = "客户端"; } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话