2

この例に基づいて、単純な WCF パブリッシュ/サブスクライブを実行しています。私は、reliableSession を有効にして netTcpBinding を使用しています。機能はすべて正常に動作します (サブスクライブしたクライアントは、公開されたデータを期待どおりに受信します) が、しばらくアイドル状態が続くと、ある時点で接続がタイムアウトになります。パブリッシャーがタイムアウト時に再接続するように設定できますが、サブスクライブしているクライアントは失われます。それらを取り戻す方法はありますか?他の問題を引き起こす可能性があるため、タイムアウトを増やすだけではありません。

4

1 に答える 1

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
        }
    }

その後、サービスは、クライアントが見逃したものを解決し、それらのメッセージを正しい順序で再送信できます。

この解決策は私にとってはうまくいっているようですが、これを行うにはもっと良い方法があるはずだと感じています。コメント/追加の回答は大歓迎です! :)

于 2011-06-10T15:01:31.727 に答える