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