2017-08-19 23 views
0

私はSQLデータベースのユーザーに対してオフラインに設定された簡単なコードを使用しました。Socket.io '切断イベント'が再接続後に遅すぎます。

サーバー

io.on('connection', function (socket) { 
    ApiHelper.setUserOnline(socket.token); 

    socket.on('disconnect', function() { 
     ApiHelper.setUserOffline(socket.token); 
    }); 
} 

は、ユーザが、彼はその後、再接続し、ネットワーク接続を失ったよりも、ソケットに接続、

を言うことができます。

このログを取得します。接続

  • ユーザー(彼がオンラインである)
  • ネットワークlosted。
  • ネットワークが切断されましたが、切断イベントがまだサーバーによって受信されていないため、ユーザーはまだオンラインです。
  • ネットワークに接続してからソケットに接続します。ユーザーはまだオンラインです。
  • 以前にサーバーとユーザーによって受信された切断イベントは、データベースでオフラインに設定されています。 しかし、待っているユーザーが再接続しただけなので、実際にはユーザーはオンラインになっている必要があります。我々はユーザーを見たので、後半の火力切断イベントの

は、データベース内のオフラインになっています。

どのようにこの問題を解決できますか?

+1

は、各セッションには、一意のIDか何かを持っていますそんな? – tobifasc

+0

@tobifascはい、トークンは各ユーザーの一意のIDです。 – ocanal

+1

私は各ユーザーではなく、ユーザーが作成したセッションごとに使用します。接続されたログと切断されたログにセッションIDを追加できます。したがって、ユーザーが古いセッションIDで切断したときに、新しいセッションIDを既に取得している場合、その新しいセッションIDから切断されることはありません。あなたはアイデアを得ますか? – tobifasc

答えて

1

私はSQLデータベースにsocket.idを格納することをお勧めします。ユーザーログイン/接続時にまずuser.accountがオンラインかどうかを確認してください。

それがオンラインになっている場合、そのアカウントは新しいsocket.id

ためと置き換えることによって、デシベルでそれを置き換えるものは何でも、別のウィンドウ/デバイス/から開かれたことを通知するために、古いsocket.idを使用接続が切断されたときに、そのアカウントを使用している現在のアクティブなクライアント(socket.id)であるかどうかを実際に知ることができます。 disconnectionでそう

socket.idを切断が(つまり:現在接続されているかどうか)データベースか であるかどうかを確認

io.on('connection', function (socket) { 
    /* check if the account associated to this socket was 
     previously associated to another socket.id ... 
    (that might be currently connected or about to disconnect (lost connection) 
    */ 
    if(thisAccountWasOnlineBefore){ 
    socket.to(old.socket.id).emit('exit', 'account opened from another session'); 
    } 
    //pass also the socket.id so you can store it in the db 
    ApiHelper.setUserOnline(socket.id, socket.token); 

    socket.on('disconnect', function() { 
     //check if socket.id is associated to any account in the db 
     // if true : remove the socket.id and set as account status : offline 
    }); 
} 
+0

ユーザが接続する度に、新しい一意の 'socket.id'が得られますので、データベースに格納する意味はありません:1.接続するときに' socket.id'がデータベースにないときは2、切断するときは2ソケットです。IDは確かにデータベースにあります – mk12ok

+0

@ mk12okあなたが言っていることは当然のことではありませんが、新しくユニークですが、どのIDが現在どのアカウントを使用しているのかを知ることができるので、切断が発生したときに、アクティブなユーザーのソケット接続または古いユーザーの接続(現在アクティブな接続の切断を防止する)。 – EMX

+0

これは、一度に1つのインスタンスからしかアカウントにアクセスできないゲームで特に役立ちます。 (既に開かれている同じアカウントで接続すると、古いクライアントに「接続が失われました:このアカウントは別のクライアントから開かれました」というメッセージが表示されます)。 – EMX

関連する問題