WCF、双工回调、recieveTimeout netTcpBinding
我有一个主机/客户端 WCF 服务和使用 netTcpBinding 和回调方法的客户端。
<bindings>
<netTcpBinding>
<binding name="tcp_Unsecured" receiveTimeout="00:01:00" sendTimeout="00:01:00">
<security mode="None" />
<reliableSession enabled="true" ordered="true" inactivityTimeout="00:10:00"/>
</binding>
</netTcpBinding>
</bindings>
代理
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://dotnetaddict.dotnetdevelopersjournal.com/wcf.samples", ConfigurationName="AlarmServer", CallbackContract=typeof(AlarmServerCallback), SessionMode=System.ServiceModel.SessionMode.Required)]
public interface AlarmServer
{
[System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://dotnetaddict.dotnetdevelopersjournal.com/wcf.samples/AlarmServer/RegisterAlarm")]
void RegisterAlarm(System.DateTime alarmTime, string clientName, string reminderMessage);
[System.ServiceModel.OperationContractAttribute(IsOneWay = true, Action = "http://dotnetaddict.dotnetdevelopersjournal.com/wcf.samples/AlarmServer/unRegisterAlarm")]
void unRegisterAlarm(string clientName);
[System.ServiceModel.OperationContractAttribute(IsOneWay = true, Action = "http://dotnetaddict.dotnetdevelopersjournal.com/wcf.samples/AlarmServer/broadcastMessage")]
void broadcastMessage(string msg);
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public interface AlarmServerCallback
{
[System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://dotnetaddict.dotnetdevelopersjournal.com/wcf.samples/AlarmServer/SignalAlarm")]
void SignalAlarm(string reminderMessage);
[System.ServiceModel.OperationContractAttribute(IsOneWay = true, Action = "http://dotnetaddict.dotnetdevelopersjournal.com/wcf.samples/AlarmServer/displayMessage")]
void displayMessage(string msg);
}
带回调的
public MainForm()
{
InitializeComponent();
InstanceContext context = new InstanceContext(new AlarmCallback());
client = new AlarmServerClient(context);
}
客户端实例我遇到的问题是,在绑定 receiveTimeout 触发后,客户端进入故障状态并关闭客户端侦听回调。
我可以使用 sysinternals 中的 TCPVIEW 看到侦听端口丢失。
如果我保持通道繁忙,则不会触发超时,因此它不是发送到服务器/客户端的 WCF 消息中的错误,因为多个消息将正常流过。
我认为 receiveTimeout 的设计目的是提供一种方法来检测 TCP 上的 WCF 消息的回复是否失败? 为什么会出现连接错误。 看起来,如果在超时时间内没有创建回调对象,那么通道就会关闭?
我做错了什么?
Ive got a Host / Client WCF Service and client that is using netTcpBinding and a callback method.
<bindings>
<netTcpBinding>
<binding name="tcp_Unsecured" receiveTimeout="00:01:00" sendTimeout="00:01:00">
<security mode="None" />
<reliableSession enabled="true" ordered="true" inactivityTimeout="00:10:00"/>
</binding>
</netTcpBinding>
</bindings>
Proxy
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://dotnetaddict.dotnetdevelopersjournal.com/wcf.samples", ConfigurationName="AlarmServer", CallbackContract=typeof(AlarmServerCallback), SessionMode=System.ServiceModel.SessionMode.Required)]
public interface AlarmServer
{
[System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://dotnetaddict.dotnetdevelopersjournal.com/wcf.samples/AlarmServer/RegisterAlarm")]
void RegisterAlarm(System.DateTime alarmTime, string clientName, string reminderMessage);
[System.ServiceModel.OperationContractAttribute(IsOneWay = true, Action = "http://dotnetaddict.dotnetdevelopersjournal.com/wcf.samples/AlarmServer/unRegisterAlarm")]
void unRegisterAlarm(string clientName);
[System.ServiceModel.OperationContractAttribute(IsOneWay = true, Action = "http://dotnetaddict.dotnetdevelopersjournal.com/wcf.samples/AlarmServer/broadcastMessage")]
void broadcastMessage(string msg);
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public interface AlarmServerCallback
{
[System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://dotnetaddict.dotnetdevelopersjournal.com/wcf.samples/AlarmServer/SignalAlarm")]
void SignalAlarm(string reminderMessage);
[System.ServiceModel.OperationContractAttribute(IsOneWay = true, Action = "http://dotnetaddict.dotnetdevelopersjournal.com/wcf.samples/AlarmServer/displayMessage")]
void displayMessage(string msg);
}
client instance with callback
public MainForm()
{
InitializeComponent();
InstanceContext context = new InstanceContext(new AlarmCallback());
client = new AlarmServerClient(context);
}
The problem I have is that after the binding recieveTimeout triggers, the client goes into a faulted state and closes the clients listening callback.
I can see the listening port drop using TCPVIEW from sysinternals.
If I keep the channel busy, the time out does not trigger, so its not a fault in the WCF message to the Server/Client, as multiple messages will flow through ok.
I thought the receiveTimeout was designed to provide a way to detect if a reply from the WCF message over TCP failed?
Why is it faulting the connection.
It almost appears that if there are no callback object created for the timeout period, the channel is then closed?
What am I doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
接收超时似乎会导致回调主机服务在达到最大计数后出现故障。这是 23.59 小时或默认值 1 分钟。
我可以通过将 receivetimeout 设置为 Infinate 来解决超时问题
,但这让我现在想知道我是否真的在 WFC 中使用正确的工具进行服务器/客户端通信。我希望主机/服务器在文件服务器上运行,并且多个远程客户端连接到它。客户端会通过心跳对服务器进行 ping 操作,有时服务器可能会向客户端发送命令。我使用远程处理或 tcpsockets 并使用“客户端轮询方法”来执行此操作,其中命令在数据库中排队,当客户端每 10 分钟轮询服务器一次命令时,如果该唯一客户端有待处理的命令,则它得到它。这工作正常,并且优点是没有 1000 个到服务器的开放 tcp 套接字连接,因为客户端只会随机连接和断开连接。
但我决定尝试 WCF(毕竟这不是取代 Remoting 的最新版本吗?),当我发现 Duplex 时,我想,我会使用它......
现在我想我没有明白 WCF Duplux 的用途???
帮助我错过这里的概念吗???
Seems the Receivetime out causes the callback host service to fault after it reaches its max count. Which is 23.59 hrs or the default of 1 minute.
I can resolved the timeout issue with setting receivetimeout to Infinate
But this has me now wondering if im really using the right tool in WFC for Server/Client communications. I want a Host/Server to be running on a file server, and multiple remote clients connected to it. The client will ping the server with a heartbeat, and occasionally the server might send a command to the client. I was doing this with remoting or tcpsockets and using a "client polling method", where commands where quued in a database and when the client polled the server for a command every 10 mins, if there was a pending command for that unique client it got it. This worked ok, and had the advantage of NOT having 1000 open tcp socket connections to the server, as client would only randomly connect and disconnect.
BUT I decided to try WCF (after all isnt this the new latest in greates replacing Remoting?) and when I found Duplex I thought, Id use it....
NOW Im thinking Im missing the point about what WCF Duplux is for ???
Help am I missing the concepts here???
receiveTimeout 设置的值将告诉服务在未收到应用程序消息时在通信通道出现故障之前等待多长时间。您始终可以将此超时值增加到更大的数字(默认值为 10 分钟),但您还必须增加会话不活动超时。请参阅 http://msdn.microsoft。 com/en-us/library/system.servicemodel.channels.binding.receivetimeout.aspx 了解有关这两种超时的更多信息。
当接收或不活动超时触发时,双工通道出现故障。您必须在客户端创建一个新代理才能再次与服务器通信。
在尝试调用服务器之前,您始终可以在客户端检查通道连接状态。如果通道的CommunicationState没有打开,那么你可以在调用服务器之前创建一个新的代理。
The value at which the receiveTimeout is set will tell the service how long to wait before faulting the communication channel when no application message is received. You can always increase this timeout value to a greater number (default is 10 minutes), but you then also have to increase the session inactivity timeout. Please see http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.binding.receivetimeout.aspx for more information on both of these timeouts.
When the receive or inactivity timeout fires, the duplex channel is faulted. You will have to create a new proxy on the client side to be able to communicate with the server again.
You can always check the channel connection status on the client side before trying to call the server. If the CommunicationState of the channel is not opened, then you can create a new proxy before calling the server.
您是否尝试过在代理创建(客户端)中使用DuplexChannelFactory?
它的使用方法如下(使用new AlarmServerClient(context)替换创建):
编辑:启用日志分析跟踪:
通过启用消息日志记录,可以分析通道通信和跟踪:
在这种情况下,跟踪能够记录“信息”。看到渠道的创建很重要。
要分析 svclog 文件,可以使用服务跟踪查看器 - Microsoft Windows SDK,通常位于 C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\SvcTraceViewer.exe
Have you tried using a DuplexChannelFactory, in the proxy creation (client)?
Here's how it's used (replace the creation using new AlarmServerClient(context)):
EDIT: Enabling log to analyse trace:
Its possible to analyse the channels communication, by enabling Message logging and Trace:
In this case, the Trace is able to log "Information". Its important to see the channels creation.
To analyse the svclog file, you can use the Service Trace Viewer - Microsoft Windows SDK, usually in C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\SvcTraceViewer.exe