2016-11-08 7 views
0

私はこの問題についての回答をしばらく読んできましたが、解決策のどれもセットアップにはうまくいかないようです。Socket.ioページの更新がルームから切断される

私はexpressと組み合わせてnodeJSサーバーを持っています。私はSocket.ioを使って個々のユーザーに通知を送信します。 (フロントエンドは角度です)

ユーザーがログインすると、彼は自分のメールアドレス(ユニーク)の名前の部屋に参加します。

io.on('connection', function (socket) { 
    socket.on('join', function(user) { 
     //list of connected users 
     connected_users.push({socket_id: socket.id, email: user.email}); 
     socket.join(user.email); 
    }); 
    ... 

joinイベントは、ときにユーザーがログインの角度から放送される

私は単に電子メールアドレスを使用することにより、そのような通知を送ることができますこの方法:

io.sockets.in(to).emit('notification', { 
    message: msg, 
    source: from, 
    destination: to, 
    event: data 
}); 

ユーザーが手動でログインすると私は以下のイベントリスナーを登録します:

socket.on('leave', function(user) { 
    //remove the user from the list 
    var index = findUserConnected(socket.id); 
    if(index != null) { 
    connected_users.splice(index, 1); 
    } 
    socket.leave(user.email); 
}); 

そして

socket.on('disconnect', function() { 
    //if the user refreshes the page, he is still in the connected users list 
    var email = findEmailUserConnected(socket.id); 
    if(email != null) { 
    //we make him join back his room 
    socket.join(email); 
    } 
}); 

技術的にはこの作品:最後にユーザーがログアウトするか、ページを更新するたびにためdisconnectハンドラがあります。ページの更新時に、ユーザーは自分の部屋に参加します。

問題はページの更新時のみです。ユーザーが彼の部屋にいるのに、io.sockets.in(email).emit('notification', {});を使用して送信された通知は受信されません。

明らかにページリフレッシュは、新しいsocket_idを生成するsocket.disconnect()を呼び出します。 socket_idを部屋などに再割り当てする方法があるかどうかはわかりません。

+0

ページをリロードすると、webSocket/socket.io接続を含むすべてのページリソースが破壊されます。ページを再度読み込むと、新しい接続が作成されます。永続的なセッションIDを作成するには、おそらくCookieを使用して、以前のユーザーを識別し、サーバー上の状態を復元する必要があります。 – jfriend00

+0

@ jfriend00「サーバー上の状態を復元する」とはどういう意味ですか?私はすでにページがリフレッシュされたときにsocket.joinを持っています。 – gyc

+0

'connection'イベントが発生すると、以前に部屋に設定したソケットを認識し、その状態を望むように戻す必要があります(部屋に戻し、そのソケットのIDを更新してくださいこのユーザーに属しています...通常、以前に見た特定のユーザーにこの新しい着信接続を関連付けるために、Cookieから取得した情報を使用します。 – jfriend00

答えて

1

まず、サーバー上で「切断」イベントを受信すると、そのソケット上の接続が終了することを意味します。だから、あなたが今やっているように、同じソケットを部屋に戻すための使用はありません。

socket.on('disconnect', function() { 
    var email = findEmailUserConnected(socket.id); 
    if(email != null) { 
     socket.join(email); // this would never work because this socket connection is not going to exist anymore. 
    } 
}); 

私の提案は、ユーザーが常に部屋(電子メール)に戻し、新たな接続が行われるたびに加入していることを確認することです。新しい接続ごとにjoinイベントを送信することを追加することで簡単に実行できます。クライアント側のコードで は

var socket = io(); 
socket.on('connect', function() { // 'connect' event is received on client on every connection start. 
    socket.emit('join', user); // where 'user' is your object containing email. 
}) 

それは、新しい接続が確立されるたびにイベントがサーバーと「socket.onに送信され参加することを保証します。この方法で(」参加、...)」リスナーで操作を行いますサーバーが新しいソケットを部屋に追加します。これがうまくいくといいでしょう:)

関連する問題