我有一个使用netTcpBinding和回调方法的主机/客户端WCF服务和客户端。
<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);
}
我遇到的问题是绑定recieveTimeout触发后,客户端进入故障状态并关闭客户端侦听回调。
我可以在sysinternals中看到使用TCPVIEW的监听端口丢弃。
如果我保持频道忙,超时不会触发,所以它不是WCF消息到服务器/客户端的错误,因为多条消息将流过ok。
我认为receiveTimeout旨在提供一种方法来检测来自TCP的WCF消息的回复是否失败? 为什么它会断开连接。 几乎看来,如果在超时期限内没有创建回调对象,那么通道会关闭吗?
我做错了什么?
答案 0 :(得分:6)
似乎Receivetime out导致回调主机服务在达到其最大计数后出现故障。这是23.59小时或默认为1分钟。 我可以通过将receivetimeout设置为Infinate来解决超时问题
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_AlarmServer" receiveTimeout="infinite" >
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
但是现在我想知道我是否真的在WFC中使用正确的工具进行服务器/客户端通信。我希望主机/服务器在文件服务器上运行,并且多个远程客户端连接到它。客户端将使用心跳对服务器执行ping操作,有时服务器可能会向客户端发送命令。我使用远程处理或tcpsockets并使用“客户端轮询方法”执行此操作,其中命令在数据库中进行查询以及客户端每隔10分钟轮询服务器以获取命令,如果有唯一客户端的挂起命令它。这工作正常,并且具有不与服务器进行1000个打开的tcp套接字连接的优点,因为客户端只会随机连接和断开连接。 但我决定尝试WCF(毕竟这不是最新的greates取代Remoting吗?)当我发现Duplex我想,我用它.... 现在我想我错过了关于WCF Duplux是什么的观点???
帮助我错过了这里的概念???
答案 1 :(得分:4)
设置receiveTimeout的值将告诉服务在没有收到应用程序消息时,在通信通道发生故障之前需要等待多长时间。您始终可以将此超时值增加到更大的数字(默认值为10分钟),但您还必须增加会话不活动超时。有关这两个超时的详细信息,请参阅http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.binding.receivetimeout.aspx。
当接收或不活动超时触发时,双工通道出现故障。您必须在客户端创建一个新代理才能再次与服务器通信。
在尝试呼叫服务器之前,您始终可以检查客户端的通道连接状态。如果未打开通道的CommunicationState,则可以在调用服务器之前创建新代理。
答案 2 :(得分:3)
您是否尝试在代理创建(客户端)中使用 DuplexChannelFactory ? 以下是它的使用方法(使用 new AlarmServerClient(context)替换创建):
AlarmServer proxy = new DuplexChannelFactory<AlarmServer>(context,"YourAlarmServerEndpoint").CreateChannel();
编辑:启用日志以分析跟踪:
可以通过启用消息记录和跟踪来分析通道通信:
<system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging" switchValue="Warning, ActivityTracing">
<listeners>
<add type="System.Diagnostics.DefaultTraceListener" name="Default">
<filter type="" />
</add>
<add name="ServiceModelMessageLoggingListener">
<filter type="" />
</add>
</listeners>
</source>
<source name="System.ServiceModel" switchValue="Information,ActivityTracing"
propagateActivity="true">
<listeners>
<add type="System.Diagnostics.DefaultTraceListener" name="Default">
<filter type="" />
</add>
<add name="ServiceModelTraceListener">
<filter type="" />
</add>
</listeners>
</source>
</sources>
<sharedListeners>
<add initializeData="Your_svclog_file_here"
type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
name="ServiceModelMessageLoggingListener" traceOutputOptions="Timestamp">
<filter type="" />
</add>
<add initializeData="Your_svclog_file_here"
type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
name="ServiceModelTraceListener" traceOutputOptions="Timestamp">
<filter type="" />
</add>
</sharedListeners>
<trace autoflush="true" />
在这种情况下,Trace能够记录“信息”。看到创建频道非常重要。
要分析svclog文件,您可以使用服务跟踪查看器 - Microsoft Windows SDK,通常位于C:\ Program Files \ Microsoft SDKs \ Windows \ v6.0A \ bin \ SvcTraceViewer.exe