什么可能导致WCF双工服务间歇性超时?

时间:2016-11-01 17:46:27

标签: c# web-services wcf duplex

我创建了一个简单的WCF双工服务作为概念验证/学习练习,定义如下:

// web service definition
[ServiceContract(CallbackContract = typeof(IDuplexClientCallback))]
public interface IDuplexWebService
{
    [OperationContract(IsOneWay = true)]
    void Command(CommandRequest command);
}

// service implementation decorated with:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]

// callback contract
public interface IDuplexClientCallback
{
    [OperationContract(IsOneWay = true)]
    void Send(string message);
}

// callback implementation decorated with:
[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Single)]

要求双工的原因是服务需要向连接的客户端发送未经请求的更新。正常的使用周期是:

  1. 客户端调用Command()服务方法(不等待同步回复)。
  2. 服务对命令进行排队以进行处理。
  3. 服务在处理完成后通过Send()响应客户端。
  4. 这很常见,但偶尔从Service到Client的Send()回调阻塞60秒(超时),导致Service无法接受新命令。似乎没有太多的模式,当发生这种情况时,在被阻止的命令之间可以有少至两个和多达二十个成功的命令。

    每个客户端创建并缓存一个Channel以与服务进行通信。同样,服务为每个客户端创建并缓存一个CallbackChannel。我正在使用wsHttpBinding和很大程度上的默认设置(相对较新的WCF)。通过调试,我确定通道没有过早关闭。客户端回调的实现只是将收到的消息写入控制台。

    我在服务器和客户端都添加了一些日志记录语句,希望能够证明这个问题:

    成功的命令,你可以看到很快执行:

    17:12:35->INFO: [CLIENT] Submitting command: hello world 
    17:12:35->INFO: [SERVER] Received command request.
    17:12:35->INFO: [SERVER] Queuing action. 
    17:12:35->INFO: [SERVER] Action queued, exiting. 
    17:12:35->INFO: [SERVER] Processing complete. Sending response... 
    17:12:35->INFO: [SERVER] Finished sending response. Took: 0.0068685 seconds. 
    17:12:35->INFO: [CLIENT] Received response of length 21.
    

    被阻止的命令:

    17:12:49->INFO: [CLIENT] Submitting command: hello moon
    17:12:49->INFO: [SERVER] Received command request.
    17:12:49->INFO: [SERVER] Queuing action.
    17:12:49->INFO: [SERVER] Action queued, exiting.
    17:12:49->INFO: [SERVER] Processing complete. Sending response...
    17:12:49->INFO: [CLIENT] Received response of length 21.
    17:12:51->INFO: [CLIENT] Submitting command: hello mars
    17:12:51->INFO: [SERVER] Received command request.
    17:12:51->INFO: [SERVER] Queuing action.
    17:12:51->INFO: [SERVER] Action queued, exiting.
    17:13:49->INFO: [SERVER] Finished sending response. Took: 60.0077729 seconds. ('hello moon')
    17:13:49->INFO: [SERVER] Processing complete. Sending response...
    17:13:49->INFO: [SERVER] Finished sending response. Took: 0.0076397 seconds. ('hello mars')
    17:13:49->INFO: [CLIENT] Received response of length 21.   
    

    此处向'hello moon'发送响应已花费60秒(在此期间另一个命令已排队)。这里60秒的数字必须是相关的 - 有些东西正在阻塞并超时。您还可以看到客户端几乎立即收到响应,但服务器未注册发送操作完成60秒。

    我还启用了跟踪,发现此错误被抛出。对我来说,单向操作会超时等待回复似乎很奇怪。

      

    System.TimeoutException:HTTP请求   ' [本地主机-URL] / Temporary_Listen_Addresses / a03cfb7c-7e6d-4444-9914-11921f85c277 / 89a796b2-aad7-49ad-8426-c2a91ddf46c0 '   已超过分配的超时00:00:59.9980000。时间   分配给这个操作可能是一个更长的一部分   超时。在System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException,HttpWebRequest request,HttpAbortReason abortReason)   at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)   在System.ServiceModel.Channels.RequestChannel.Request(消息消息,TimeSpan超时)   在System.ServiceModel.Channels.RequestOneWayChannelFactory.RequestOutputChannel.OnSend(消息消息,TimeSpan超时)   在System.ServiceModel.Channels.OutputChannel.Send(消息消息,TimeSpan超时)

    我一直在努力诊断这一天并且已经撞墙了。我已经为服务尝试了不同的并发模式,问题仍然存在。这可能是什么原因,以及我可以采取哪些进一步措施来追踪它?我需要做些什么来管理我的联系吗?我需要调整一些配置吗?如果有必要,我可以添加更多代码,但这是一个很长的问题。

0 个答案:

没有答案