WCF发布/订阅:如何处理客户端超时以免错过信息?

时间:2011-05-27 08:04:25

标签: wcf timeout publish-subscribe reconnect

我有一个简单的WCF发布/订阅并运行based on this example。我正在使用netTcpBinding并启用了reliableSession。功能正常(订阅的客户端按预期接收已发布的数据),但在某些时候连接超时(如果它已闲置一段时间)。我可以将发布者设置为在超时时重新连接,但订阅的客户端将丢失。有办法让他们回来吗?我宁愿不仅仅增加超时,因为这可能会导致其他问题。

1 个答案:

答案 0 :(得分:0)

我最终想出的解决方案是为发布的每条消息分配一个唯一的标识符,并将发布的消息缓存在服务适配器中(在我将回调存储到订阅客户端的同一位置。每当我发布消息后,订阅者将收到消息相应的唯一ID。然后,订阅者可以使用channel.Faulted事件重新连接并使用特殊方法重新订阅服务,该方法将最后收到的消息ID作为一个参数。

服务代码:

    /// <summary>
    /// Operation used by the subscriber to subscribe to events published.
    /// </summary>
    public void Resubscribe(int lastReceivedMessageId)
    {
        // Get callback contract
        IPubSubCallback callback = OperationContext.Current.GetCallbackChannel<IPubSubCallback>();
        ThreadPool.QueueUserWorkItem(delegate(object state)
        {
            adapter.Resubscribe(lastReceivedMessageId, callback);
        }); 
    }

适配器代码:

/// <summary>
    /// Operation used by the subscriber to resubscribe to events published.
    /// </summary>
    public void Resubscribe(int lastReceivedMessageId, IPubSubCallback callback)
    {
        try
        {
            // Send the subscriber any missed messages
            foreach (KeyValuePair<int, string> missedMessage in publishedMessages.Where(x => x.Key > lastReceivedMessageId))
            {
                callback.MessagePublished(missedMessage.Value, missedMessage.Key);
            }

            // Add the subscriber callback to the list of active subscribers
            if (!callbacks.Contains(callback))
            {
                callbacks.Add(callback);
            }
        }
        catch
        {
            // ignore subscription, callbacks failed again
        }
    }

然后,该服务可以解决客户端错过的内容,并以正确的顺序重新发送这些消息。

这个解决方案似乎对我有用,但我觉得必须有更好的方法来做到这一点。评论/其他答案非常欢迎! :)