web-dev-qa-db-ja.com

nodejs websocketが切断されたソケットを検出する

Nodejs websocketサーバーがあり、次の問題があります。

クライアントがサーバーに接続して正常に終了すると、それらのソケットでoncloseメソッドが呼び出され、閉じたソケットでクリーンアップ操作を実行します。

ネットワークが原因でクライアントが切断した場合、oncloseメソッドは呼び出されません。タイムアウトを設定する必要があるので、oncloseはタイムアウト後に自動的に呼び出されますか?

Nodejsのwebsocketサーバーに ws パッケージを使用しています

9
Pavan K

デフォルトのws実装には、クライアント側からのネットワーク切断のためのコールバックがありません

あなたはkeepAlive実装を見つけることができます ここ

17
Pavan K

さて、私は2つの例であなたの質問に答えようとします。それらの両方を分析して、それらがどのように機能するかを学習してください。彼らはテストされ、動作しています。

1- WebSocket:

サーバ:

var WebSocketServer = require('websocket').server;
var http = require('http');

var server = http.createServer(function(request, response) {
    console.log((new Date()) + ' Received request for ' + request.url);
    response.writeHead(404);
    response.end();
});
server.listen(3000, function() {
    console.log((new Date()) + ' Server is listening on port 3000');
});

wsServer = new WebSocketServer({
    httpServer: server,
    autoAcceptConnections: false
});

function originIsAllowed(Origin) {
  return true;
}

wsServer.on('request', function(request) {
    if (!originIsAllowed(request.Origin)) {
      request.reject();
      console.log((new Date()) + ' Connection from Origin ' + request.Origin + ' rejected.');
      return;
    }

    var connection = request.accept('echo-protocol', request.Origin);
    console.log((new Date()) + ' Connection accepted.');
    connection.on('message', function(message) {
        if (message.type === 'utf8') {
            console.log('Received Message: ' + message.utf8Data);
            connection.sendUTF(message.utf8Data);
        }
        else if (message.type === 'binary') {
            console.log('Received Binary Message of ' + message.binaryData.length + ' bytes');
            connection.sendBytes(message.binaryData);
        }
    });
    connection.on('close', function(reasonCode, description) {
        console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
    });
});

クライアント:

<!DOCTYPE html>
<html>
<head>
    <title>Web socket Experiment</title>
    <script type="text/javascript">
        function callWebSocket() {

            var socket = new WebSocket("ws://localhost:3000", 'echo-protocol');

            socket.onopen = function () {
                alert("Hello, Connected To WS server");
            };

            socket.onmessage = function (e) {
                alert("The message received is : " + e.data);
            };
            socket.onerror = function (e) {
                alert("An error occured while connecting... " + e.data);
            };
            socket.onclose = function () {
                alert("hello.. The coonection has been clsoed");
            };

        }
    </script>
</head>

<body>
    <input type="button" value="Open Connecton" onclick="callWebSocket()" />
</body>
</html>

2- Socket.io:

サーバ:

var http = require('http');
    var app = require('express')();
    var httpServer = http.createServer(app)
    var io = require('socket.io')(httpServer);

app.get('/', function(req, res) {
    res.sendfile(__dirname + '/index.html');
});

io.on('connection', function(socket) {
    socket.emit('news', {
        hello: 'world'
    });
    socket.on('my other event', function(data) {
        console.log(data);
    });
    socket.on('disconnect', function(data) {
        console.log('disconnect!');
    });
});

httpServer.listen(3000);

クライアント:

<html>
<head>
<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<script>
  var conn_options = {
    'sync disconnect on unload':false
  };
  var socket = io.connect('http://localhost:3000',conn_options);
  socket.on('news', function (data) {
    console.log(data);
    socket.emit('my other event', { my: 'data' });
  });
</script>
</head>
<body>
</body>
</html>
3
Ehsan

切断を検出するには、いくつかのトラフィックが必要です。アプリケーションが一定のトラフィックを生成する場合、何かが受信されるたびにカウンターをリセットするようなことを行い、カウンターが不足すると接続が失敗したと考えることができます。

それ以外の場合は、WebSocketが提供するpingを使用できるはずです。これらはブラウザーで公開されていませんが、Node.jsのWebSocketライブラリを使用すると、それらをオンにして、pingが失敗した場合に通知を受け取ることができます。

2
gzost