WCF C#技术问题:单次请求下通过NetNamedPipe绑定发送多响应
WCF NetNamedPipe绑定实现单次请求多响应方案
一、双工通信(Callback Contract)方案
NetNamedPipe绑定原生支持双工模式,这是实现服务器主动向客户端多次推送响应的最优方案——通过回调契约,可在单次客户端请求后,持续向同一客户端发送定时响应。
1. 定义契约
首先定义回调接口,用于服务器向客户端推送消息:
public interface IMyCallback { [OperationContract(IsOneWay = true)] void PushResponse(string message); }
接着定义服务契约,指定回调类型并启用会话:
[ServiceContract(CallbackContract = typeof(IMyCallback), SessionMode = SessionMode.Required)] public interface IMyService { [OperationContract] void InitiateMultipleResponses(int intervalMs, int responseCount); }
SessionMode.Required用于维持客户端与服务器的会话关联,确保推送的响应仅发送给发起请求的客户端。
2. 实现服务逻辑
服务类中获取客户端回调通道,按指定间隔推送响应:
public class MyService : IMyService { public void InitiateMultipleResponses(int intervalMs, int responseCount) { var callback = OperationContext.Current.GetCallbackChannel<IMyCallback>(); for (int i = 0; i < responseCount; i++) { // 模拟定时等待,实际场景可替换为业务逻辑触发 Task.Delay(intervalMs).Wait(); callback.PushResponse($"响应 {i+1}:{DateTime.Now:yyyy-MM-dd HH:mm:ss}"); // 检查回调通道状态,避免客户端断开后报错 if (((ICommunicationObject)callback).State != CommunicationState.Opened) break; } } }
3. 服务端与客户端配置及实现
服务端配置(App.config)
<system.serviceModel> <services> <service name="YourNamespace.MyService"> <endpoint address="net.pipe://localhost/DuplexNamedPipeService" binding="netNamedPipeBinding" contract="YourNamespace.IMyService"/> </service> </services> </system.serviceModel>
NetNamedPipe绑定默认支持双工,无需额外配置双工模式。
客户端实现
客户端需实现回调接口,并创建双工代理:
// 回调处理类,接收服务器推送 public class CallbackReceiver : IMyCallback { public void PushResponse(string message) { Console.WriteLine($"收到服务器响应:{message}"); } } // 客户端调用逻辑 var callbackReceiver = new CallbackReceiver(); var instanceContext = new InstanceContext(callbackReceiver); var factory = new DuplexChannelFactory<IMyService>( instanceContext, new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/DuplexNamedPipeService")); var serviceProxy = factory.CreateChannel(); // 发起请求,要求服务器每秒推送一次,共5次 serviceProxy.InitiateMultipleResponses(1000, 5); // 保持客户端运行,直到接收完所有响应 Console.WriteLine("等待服务器推送响应..."); Console.ReadLine(); // 关闭资源 ((ICommunicationObject)serviceProxy).Close(); factory.Close();
二、关键注意事项
- 客户端需保持进程存活,直到接收完所有推送,否则会中断会话导致推送失败。
- 服务端必须检查回调通道状态,防止客户端意外断开后抛出通信异常。
- 若需高并发场景,建议使用异步操作(
async/await)替代同步等待,避免阻塞服务线程。 - 会话模式不可省略,双工通信依赖会话来绑定客户端与回调通道。
内容的提问来源于stack exchange,提问作者Prakash
相关产品推荐
相关产品推荐

