Socket.io: ブラウザの更新時に古い接続をエミットし、古い接続を保持する

作成日 2016年02月01日  ·  4コメント  ·  ソース: socketio/socket.io

こんにちは、

現在のDate()を単一のクライアントに送信する単純なsocket.ioサーバーテストセットアップがあります。

サーバーは1秒ごとにDate()を1つのクライアントに送信(送信)します。

ブラウザウィンドウを更新しても、接続は1つですが、サーバーは2つの接続を送信します。

ブラウザウィンドウを更新しても、接続は1つですが、サーバーは3つの接続を出力します。

ブラウザウィンドウを更新しても、接続は1つですが、サーバーは4つの接続を出力します。

などなど...

数時間後でも、切断されたクライアントはサーバーから送信されています。

クライアントが接続されていない状態で、サーバーが古い接続をドロップ/クローズすることを期待していました。

これは予想される動作ですか?

Nodev5.4.1でSocket.iov1.4.5を使用しています

コードサンプルは次のとおりです。

io.on('connection', function (socket) {

  // console.log(socket.connected);
  console.log('===================');

  setInterval(() => {
    console.log(socket.conn.id);
    socket.emit('data', { ts: new Date() });
  }, 1000);

});

2秒ごとにブラウザを更新したときのconsole.logの出力は次のとおりです。

各ブラウザの更新が送信されているsocket.conn.idを確認できます。

❯ node app.js                                                                                                                                       ⏎
===================
kkizbfn-82gNOsyAAAAA
kkizbfn-82gNOsyAAAAA
===================
kkizbfn-82gNOsyAAAAA
m_ft38Y4XEY7W97VAAAB
kkizbfn-82gNOsyAAAAA
m_ft38Y4XEY7W97VAAAB
===================
kkizbfn-82gNOsyAAAAA
m_ft38Y4XEY7W97VAAAB
xH09a5Olle4A-HSNAAAC
kkizbfn-82gNOsyAAAAA
m_ft38Y4XEY7W97VAAAB
xH09a5Olle4A-HSNAAAC
===================
m_ft38Y4XEY7W97VAAAB
xH09a5Olle4A-HSNAAAC
kkizbfn-82gNOsyAAAAA
_GmZXIXg8VgUrdKlAAAD
m_ft38Y4XEY7W97VAAAB
xH09a5Olle4A-HSNAAAC
kkizbfn-82gNOsyAAAAA
_GmZXIXg8VgUrdKlAAAD

何時間も接続されたクライアント(ブラウザ)がない場合でも、古い接続はまだ送信されています。

最も参考になるコメント

@StevenBockああOK ..うん、それはすべて良いです-ありがとう!

この他の例でも同じ問題があります。

ファイルを末尾に追加して、新しい各行をクライアントに送信したいと思います。

npm'tail 'モジュールを使用すると、このコードは正常に機能しますが、古い接続の問題を保持する必要があります。

const io = require('socket.io')(8080);

const Tail = require('tail').Tail;
const tailTmpFile = new Tail("./tmp.txt");

io.on('connection', function (socket) {

  console.log(socket.conn.id);

  tailTmpFile.on("line", function (data) {
      console.log('emitting Yes: ', socket.conn.id);
      socket.emit('file', { data: data, ts: Date() });
  });

});

どういうわけか、ソケットが切断されたときにテールイベント(tailTmpFile.on)を破棄する必要があります。

全てのコメント4件

clearIntervalを使用して、切断時に間隔をクリアする必要があります。

var oneSecondInterval = setInterval(() => {
    console.log(socket.conn.id);
    socket.emit('data', { ts: new Date() });
  }, 1000);

socket.on('disconnect', function(){
    clearInterval(oneSecondInterval);
});

これにより、古い接続を保持できなくなります。

@StevenBockああOK ..うん、それはすべて良いです-ありがとう!

この他の例でも同じ問題があります。

ファイルを末尾に追加して、新しい各行をクライアントに送信したいと思います。

npm'tail 'モジュールを使用すると、このコードは正常に機能しますが、古い接続の問題を保持する必要があります。

const io = require('socket.io')(8080);

const Tail = require('tail').Tail;
const tailTmpFile = new Tail("./tmp.txt");

io.on('connection', function (socket) {

  console.log(socket.conn.id);

  tailTmpFile.on("line", function (data) {
      console.log('emitting Yes: ', socket.conn.id);
      socket.emit('file', { data: data, ts: Date() });
  });

});

どういうわけか、ソケットが切断されたときにテールイベント(tailTmpFile.on)を破棄する必要があります。

@StevenBockOK素晴らしい-わかった。

このコードは、切断時にイベントリスナーを削除します。

io.on('connection', function (socket) {

  console.log(socket.conn.id);

  var emitLine = function () {
    var callback = function (data) {
      socket.emit('file', { data: data, ts: Date() });
    }
    tailTmpFile.on("line", callback);

    // dispose function
    return function() {
      tailTmpFile.removeListener('line', callback);
    }
  }();

  socket.on('disconnect', function () {
    // dispose tail file listener
    emitLine();
  });

});

返信に時間を割いていただきありがとうございます、それは本当に正しい方向に私を設定しました。

乾杯。

喜んでお手伝いします!

このページは役に立ちましたか?
0 / 5 - 0 評価