nodejs socket 怎么检测客户端主动断开连接

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了nodejs socket 怎么检测客户端主动断开连接相关的知识,希望对你有一定的参考价值。

参考技术A 根据 https://github.com/LearnBoost/socket.io-spec 文档中说是在transport连接 (就是TCP)Close后再等一段时间(15秒,可配置)释放资源。我们知道一般TCP 不会轻易Close,网站没数据,可能连接一直存在着。
所以有两种思路,一个是自己在在Scoket.io的业务层设置定时器,超过一段时间无业务数据,释放socket.io的资源。另一种就是把TCP连接超时时间设短,不过要注意socket.io的socket不是node.js的socket,可以参考以下代码:
io.sockets.on(‘connection’, function (socket)
socket.manager.transports[socket.id].socket.setTimeout(15000);
//…

如果client关闭后,大约15+15秒之后会释放资源。本回答被提问者采纳

nodejs websocket检测断开连接的套接字

【中文标题】nodejs websocket检测断开连接的套接字【英文标题】:nodejs websocket detect disconnected socket 【发布时间】:2016-05-31 22:37:52 【问题描述】:

我有一个 nodejs websocket 服务器,但我遇到了以下问题。

当我的客户端连接到服务器并正常终止时,在这些套接字上调用 onclose 方法,我对关闭的套接字执行清理操作。

客户端因网络断开连接时,不会调用onclose方法。是否需要设置任何超时,以便在超时后自动调用onclose

我在 nodejs 中为 websocket 服务器使用ws 包

【问题讨论】:

【参考方案1】:

默认的 ws 实现没有从客户端断开网络的回调

你可以找到一个keepAlive实现here

【讨论】:

【参考方案2】:

我会尝试用两个例子来回答你的问题。尝试分析它们并了解它们的工作原理。它们都经过测试并且可以正常工作。

1- 网络套接字:

服务器:

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>

【讨论】:

我忘了提到我正在使用来自 npm 的 ws 包作为 websocket 服务器。 npmjs.com/package/ws。似乎它没有通知断开连接。【参考方案3】:

要检测断开连接,您需要有一些流量。如果您的应用程序产生持续的流量,那么您可以在每次接收到某些内容时执行诸如重置计数器之类的操作,并在计数器用完时考虑连接失败。

否则,您应该能够使用 WebSocket 提供的 ping。这些不会在浏览器中公开,但您的 Node.js 的 WebSocket 库可能允许您打开它们并在 ping 失败时收到通知。

【讨论】:

pingpong 是 WebSocket 协议的一部分,应该可以工作,但是,您需要实现某种计数器以检测断开的连接。【参考方案4】:

可以在官方库documentation查看。我不想在这里复制粘贴它,因为它很快就会过时。

【讨论】:

以上是关于nodejs socket 怎么检测客户端主动断开连接的主要内容,如果未能解决你的问题,请参考以下文章

nodejs websocket检测断开连接的套接字

netty 心跳包和断线重连机制

即使在他们断开 nodeJS socket.io 之后也记住一个客户

如何判断socket客户端连接断开

Linux Socket:如何在客户端程序中检测断开的网络?

如何在nodejs中检测客户端与redis的断开连接?