2016-05-14 7 views
1

私はWCF Duplexを使用して、サーバーのWCFで購読しているユーザー間でメッセージを送受信します。 WCFには、Join(購読する)、Leave(離脱する)、SendAlert(ユーザーから他のユーザーにメッセージを送信する)という3つのメソッドがあります。クライアントが突然WCFデュプレックスでクラッシュするときに行うべきこと

using System; 
using System.Collections.Generic; 
using System.ServiceModel; 

namespace RahatWCF 
{ 
    [ServiceContract(Name = "AlertService", 
        Namespace = "RahatWCF", 
        SessionMode = SessionMode.Required, 
        CallbackContract = typeof(IAlertCallback))] 
    public interface IAlert 
    { 
     [OperationContract] 
     int JoinTheConversation(int userId); 

     [OperationContract(IsOneWay = true)] 
     void SendAlert(int senderUserId, List<int> recieversUserId, string caption, string messageText); 

     [OperationContract] 
     int LeaveTheConversation(int userId); 
    } 

    public interface IAlertCallback 
    { 
     [OperationContract(IsOneWay = true)] 
     void NotifyUserOfMessage(int senderUserId, List<int> recieversUserId, string caption, String messageText); 
    } 

    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.PerCall)] 
    public class AlertService : IAlert 
    { 
     private static List<IAlertCallback> _callbackList = new List<IAlertCallback>(); 

     public AlertService() { } 

     public int JoinTheConversation(int userId) 
     { 
      IAlertCallback registeredUser = OperationContext.Current.GetCallbackChannel<IAlertCallback>(); 

      if (!_callbackList.Contains(registeredUser)) 
       _callbackList.Add(registeredUser); 

      return _callbackList.Count; 
     } 

     public int LeaveTheConversation(int userId) 
     { 
      IAlertCallback registeredUser = OperationContext.Current.GetCallbackChannel<IAlertCallback>(); 

      if (_callbackList.Contains(registeredUser)) 
       _callbackList.Remove(registeredUser); 

      return _callbackList.Count; 
     } 

     public void SendAlert(int senderUserId, List<int> recieversUserId, string caption, string messageText) 
     { 
      _callbackList.ForEach(
       delegate (IAlertCallback callback) 
       { 
        callback.NotifyUserOfMessage(senderUserId, recieversUserId, caption, messageText); 
       }); 
     } 
    } 
} 

上記のコードは、私はサーバ側に実装WCFデュプレックスである:以下は、サーバ側のコード(サーバにおけるAlertService WCFで二重)です。ユーザーがアプリケーションにログインすると、私のWCFクライアントアプリケーションがこのWCFに参加します。ユーザーがアプリケーションからログアウトすると、クライアントアプリケーションはWCFを終了します。問題は、ユーザーが突然アプリケーションを終了し、クライアントアプリケーションからログアウトしないと、後で他のユーザーにメッセージを送信できなくなることです。私は問題をチェックして、ユーザーがログインしたとき(ジョイン)、ログアウトしないと(leave)、サーバーで2つのチャンネルが作成され、この状況でSendAlertがもう機能しないことを確認します。どうすればこの問題を解決できますか?

答えて

0

タイムアウトは、デュプレックスチャネル(送受信されたメッセージがない場合)のキー設定です。短くしておくと、チャンネルに障害が発生します。サーバーからの応答を送信すると、障害の発生したクライアントチャネルに反応し、既知のチャネルから応答を取り除くことができます。クライアントの障害よりもサーバーに再参加する必要がある場合その場合、あなたはあなたのサービスから他のコールバックを削除することができます。

+0

私は 'receiveTimeout'と 'inactivityTimeout'を増やしましたが、時には(なぜ私にはわからない)、エラーが発生します。 '通信オブジェクトSystem.ServiceModel.Channels.ServiceChannelは通信に使用できません中止されました。このエラーを解決するにはどうすればよいですか? – Mohsen

+0

[再接続ロジック](http://stackoverflow.com/questions/14547034/wcf-channelfactory-and-channels-caching-reusing-closing-and-recovery/22124269#22124269)をご覧になることはできますが、あなたが行うことができるのはチャネルを再作成することだけです。 –

+0

ありがとうございます。確認してお知らせします。 – Mohsen

関連する問題