[英]WCF NetTcp duplex channel independent communication
I want to create a duplex NetTcp service. 我想创建一个双工NetTcp服务。 I am not sure what is the best approach.
我不确定什么是最好的方法。 I have a client that periodically sends it's status to the server and I have a server that has to send periodically data that is independent of any client request.
我有一个客户端,该客户端定期将其状态发送到服务器,并且我的服务器必须定期发送独立于任何客户端请求的数据。 Because i want avoid two connections and don't know anything about the clients at the server, I have to use the connection that is opened by the client.
因为我要避免两个连接,并且对服务器上的客户端一无所知,所以我必须使用客户端打开的连接。 So like I said the client sends periodically status information.
因此,就像我说的那样,客户端会定期发送状态信息。 But how do I use the connection channel established from the client independantly for sending data to the client.
但是,我如何独立使用从客户端建立的连接通道将数据发送到客户端。 Also the data send from server to client does need a response.
另外,从服务器发送到客户端的数据确实需要响应。
[ServiceContract(CallbackContract = typeof(IStatusServiceCallBack))]
public interface IStatusService
{
[OperationContract]
void SendStatus(int statusCode, string statusMessage);
}
public interface IStatusServiceCallBack
{
// I know IsOneWay=true cannot work, but how to return value????
[OperationContract(IsOneWay = true)]
int SendPayTransaction(PayTransaction payTransaction);
}
public class StatusService : IStatusService
{
public IStatusServiceCallBack Proxy
{
get
{
return OperationContext.Current.GetCallbackChannel
<IStatusServiceCallBack>();
}
}
public void SendNotification(int statusCode, string statusMessage)
{
Console.WriteLine($"\nClient status : {(statusCode)} {statusMessage}");
}
// Is this possible???
public int SendPayTransaction(PayTransaction payTransaction){
return Proxy.SendPayTransaction(payTransaction)
}
}
class Program
{
static void Main(string[] args)
{
var svcHost = new ServiceHost(typeof(NotificationService));
svcHost.Open();
bool closeService = false;
do{
string command = Console.ReadLine();
if(command == "Send"){
// Is this possible???????
int result = svcHost.SendPayTransaction(new PaymentTransaction(){Amount = 5.50});
Console.WriteLine($"Result of payment : {result}");
} else if (command == "exit"){
closeService = true;
}
}while(!closeService);
}
}
You're right that you need to use connection established by client. 没错,您需要使用客户端建立的连接。 In order to do this you have to perform several steps:
为此,您必须执行几个步骤:
PerSession
(or Singleton
) instance context mode for your service. PerSession
(或Singleton
)实例上下文模式。 The PerCall
one will not allow you to maintain permanent connection between client and server. PerCall
不允许您维护客户端和服务器之间的永久连接。 ReceiveTimeout
on your binding is long enough. ReceiveTimeout
上的ReceiveTimeout
足够长。 It should be longer than period between client requests, so that idle connection is not terminated by WCF infrastructure. OperationContext.Current.GetCallbackChannel<IStatusServiceCallBack>()
should be saved into private field of StatusService
when you are in SendNotification
method. SendNotification
方法时,应将OperationContext.Current.GetCallbackChannel<IStatusServiceCallBack>()
的结果保存到StatusService
私有字段中。 If your service has PerSession
instance mode, then each service class will have exactly one client. PerSession
实例模式,则每个服务类将只有一个客户端。 In case of Singleton
service you need a collection of callbacks. Singleton
服务,则需要一组回调。 StatusService
and then call method on all of them. StatusService
的静态字段中,然后在所有客户端上调用方法。 PerSession
instance context mode you cannot access service object directly, so it is still good idea to distinguish clients somehow and access them via static field or something. PerSession
实例上下文模式,则无法直接访问服务对象,因此,最好还是以某种方式区分客户端并通过静态字段或其他方式访问客户端。 You can also inject your custom factory to create service objects and then have access to them (assuming that factory also registers these objects somewhere). Beware that if client disconnects it does not invalidate callback channel immediately. 注意,如果客户端断开连接,它不会立即使回调通道无效。 You will find that out only when you call callback method - exception will be thrown back.
仅当调用回调方法时,您才会发现-异常将被抛出。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.