2016-08-30 8 views
0

SignalRを使用してMVC5に非常に簡単なチャットアプリケーションを構築しようとしています。オンラインチャットユーザーをsignalrに表示します。ユーザーをリストに追加しますが、削除しません

私はハブクラスの文字列のリストと、要素を追加したり削除したりする簡単な2つのメソッドを作成しました。クライアントを呼び出して、Jqueryを介してユーザーリストを表示します。

ユーザーの追加はうまく機能しますが、リストから削除することはできません。どんな考え?ビュー

<script src="~/Scripts/jquery.signalR-2.2.1.min.js"></script> 
<script src="~/signalr/hubs"></script> 
<script> 
    $(function() { 
     var chat = $.connection.ChatHub; 

     chat.client.updateUserList = function (users) { 
      var userList = $("#nameUsers"); 
      userList.empty(); 
      $.each(users, function (i) { 
       var li = $('<li/>') 
        .text(users[i]) 
        .appendTo(userList);      
      }); 
     }; 

     chat.client.connected = function() { 
      chat.server.addUser("@ViewBag.Username"); 
     }; 

     chat.client.disconnected = function() { 
      chat.server.removeUser("@ViewBag.Username"); 
     }; .... 

static List<string> users = new List<string>(); 

    public void AddUser(string name) 
    { 
     if (!users.Contains(name)) 
     { 
      users.Add(name); 
      Clients.All.updateUserList(users); 
     } 
     Clients.All.updateUserList(users); 
    } 
    public void RemoveUser(string name) 
    { 
     if (users.Contains(name)) 
     { 
      users.Remove(name); 
      Clients.All.updateUserList(users); 
     } 
     Clients.All.updateUserList(users); 
    } 
    public override System.Threading.Tasks.Task OnConnected() 
    {    
     Clients.Caller.connected(); 
     return base.OnConnected(); 
    } 
    public override System.Threading.Tasks.Task OnReconnected() 
    {    
     Clients.Caller.connected(); 
     return base.OnReconnected(); 
    } 
    public override System.Threading.Tasks.Task OnDisconnected(bool stopCalled) 
    {    
     Clients.Caller.disconnected(); 
     return base.OnDisconnected(stopCalled); 
    } 

私はViewBagMVCコントローラからユーザー名を取得します。

答えて

1

削除ロジックはOnDisconnectedメソッドで実行する必要があります。 Read this article from the SignalR documentation that explains lifetime events.

考えられるのは、クライアントがサーバーから既に切断されているため、removeUserメソッドを呼び出すことができないという考えです。

SignalRはOnDisconnectedメソッドを実装しました(これをオーバーライドしてロジックを追加してからbase.OnDisconnectedを返します)、サーバーは切断時間を決定します。

運が良かった!

+0

あなたの迅速な対応に感謝します。私は私の質問を更新しました。これはあなたが意味することですか? 'OnDisconnected'を含めなかったのは、' View'にもあるように私が呼び出すために使用していることが明白だと思ったからです。 – Sugafree

0

他の回答に記載されているように - 一度クライアントが切断されると、サーバー上のユーザーを削除できません。よりよい解決策は次のようになります。

static Dictionary<string, string> users = new List<string, string>(); 

private void AddUser(string connectionId, string name) 
{ 
    lock (users) 
    { 
     users[connectionId] = name; 
     Clients.All.updateUserList(users.Values.Distinct()); 
    } 
} 
private void RemoveUser(string connectionId) 
{ 
    lock (users) 
    { 
     users.Remove(connectionId); 
     Clients.All.updateUserList(users.Values.Distinct()); 
    } 
} 
public override System.Threading.Tasks.Task OnConnected() 
{    
    AddUser(Context.ConnectionId, User.Identity.Name); 
    return base.OnConnected(); 
} 
public override System.Threading.Tasks.Task OnReconnected() 
{    
    AddUser(Context.ConnectionId, User.Identity.Name); 
    return base.OnReconnected(); 
} 
public override System.Threading.Tasks.Task OnDisconnected(bool stopCalled) 
{    
    RemoveUser(Context.ConnectionId); 
    return base.OnDisconnected(stopCalled); 
} 

主な違い:サーバーのハブ・メソッドのクライアント呼び出しを信頼

  1. 避け - あなたはあらゆる種類の問題に入る...ネットワーク上の問題から、誰かにあなたが破損
  2. は、ユーザー名、connectionIdして、ユーザーをしませキーイングを得ることができるロックせずに - - これは、2つの別々のブラウザ/タブを使用するユーザーを可能にし、潜在的にあなたのシステム
  3. は、ユーザーの異議の周りにロック妨害しようとしています(前のコードでは、2つのタブにログインしてから、両方のユーザーがログオフしたように見えます)。

あなたの次の問題は、静的なユーザー(ハックのビット)ですが、それは比較してマイナーな問題です。

関連する問題