2018-03-26(websocket自动断开连接)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2018-03-26(websocket自动断开连接)相关的知识,希望对你有一定的参考价值。

参考技术A 之前做的h5游戏中的聊天功能采用的是长链接websocket,但是最近发现会有连接后1min左右就会断开连接的问题。

使用了nginx服务,如果在设置的时间内一直没有数据传输,就会自动断开连接。(默认是60s)

采用心跳维护的办法。即启动连接后设置定时器,固定时间内去发送数据来持续连接。

下图中红色区域为与服务器传输的数据,绿色代表传送的,红色代表接收到的数据。

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查看。我不想在这里复制粘贴它,因为它很快就会过时。

【讨论】:

以上是关于2018-03-26(websocket自动断开连接)的主要内容,如果未能解决你的问题,请参考以下文章

websockets 断开问题解决方案

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

初探和实现websocket心跳重连

连接后立即断开Websocket

websocket自动断开重连

WebSocket发送消息后自动断开的问题