Nodejs Websocket关闭事件调用......最终

Posted

技术标签:

【中文标题】Nodejs Websocket关闭事件调用......最终【英文标题】:Nodejs Websocket Close Event Called...Eventually 【发布时间】:2012-02-14 04:58:57 【问题描述】:

我在拼凑以下代码时遇到了一些问题。然而,所有事件都像宣传的那样工作,当客户端在没有先断开连接的情况下离线时,关闭事件不会立即得到调用。如果你给它一分钟左右,它最终会被调用。另外,我发现如果我继续向客户端发送数据,它会更快地接收到关闭事件,但不会马上。最后,如果客户端正常断开连接,结束事件就可以正常调用。

我知道这与升级和 ondata 等其他监听事件有关。

我还应该声明客户端是嵌入式设备。

client http request:
GET /demo HTTP/1.1\r\n
Host: example.com\r\n
Upgrade: Websocket\r\n
Connection: Upgrade\r\n\r\n


//nodejs server (I'm using version 6.6)
var http = require('http');
var net = require('net');
var sys = require("util");

var srv = http.createServer(function (req, res)
);

srv.on('upgrade', function(req, socket, upgradeHead) 

  socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' +
               'Upgrade: WebSocket\r\n' +
               'Connection: Upgrade\r\n' +
               '\r\n\r\n');

  sys.puts('upgraded');

  socket.ondata = function(data, start, end) 
    socket.write(data.toString('utf8', start, end), 'utf8'); // echo back
  ; 

  socket.addListener('end', function ()     
    sys.puts('end');  //works fine
  );

  socket.addListener('close', function () 
    sys.puts('close');  //eventually gets here
  );

);
srv.listen(3400);

任何人都可以提出解决方案来获取立即关闭事件吗?我试图在不使用模块的情况下保持简单。提前致谢。

【问题讨论】:

人们为这些东西编写模块是有原因的。如果您想在不使用任何先前编写的代码的情况下制作符合交叉草案的 websocket 实现,您将需要做很多工作。 @einaros +1。 socket.io 已经处理了这些问题,还有许多其他问题:***.com/questions/7192747/… @RohanSingh,我应该知道 - 我为 socket.io 编写了 websocket 代码。 【参考方案1】:

close 事件将在 TCP 套接字连接被一端或另一端关闭时被调用,当系统“没有意识到”套接字已经关闭时,极少数情况的并发症很少,但这是极少数情况。由于 WebSockets 从 HTTP 请求服务器开始,服务器可能会一直保持活动状态,直到它使套接字超时。这涉及到延迟。

在您的情况下,您尝试执行 握手,然后来回发送数据,但 WebSocket 的过程比这要复杂一些。 握手过程需要一些安全程序来验证两端(服务器和客户端),并且它是 HTTP 兼容的标头。但是不同平台和浏览器支持的不同草稿版本确实以不同的方式实现它,因此您的实现也应该考虑到这一点,并根据您需要支持的版本遵循 WebSockets 规范的官方文档。

那么通过WebSockets发送和接收数据就不是纯字符串了。通过 WebSockets 协议发送的实际数据具有数据帧层,这涉及到向您发送的每条消息添加标头。此标头包含您发送的消息、屏蔽(从客户端到服务器)、长度和许多其他内容的详细信息。数据框架再次取决于 WebSocket 的版本,因此实现会略有不同。

我会鼓励使用现有的库,因为它们已经以简洁明了的方式实现了您所需的一切,并且已在商业项目中广泛使用。 由于您的客户端是嵌入式平台,而我假设服务器也是 node.js,因此很容易在两端使用相同的库。

这里最适合的是ws - 实际的纯WebSockets。 Socket.IO 不适合您的情况,因为它是一个更加复杂和繁重的库,它有多个协议列表支持回退,并且有一些可能不是您想要的抽象。

【讨论】:

以上是关于Nodejs Websocket关闭事件调用......最终的主要内容,如果未能解决你的问题,请参考以下文章

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

websocket连接不上、报错、自动关闭,求解

WebSocket 学习--用nodejs搭建服务器

Springboot整合Websocket遇到的坑

Websocket服务器:每个会话处理关闭事件

在啥情况下 websocket 关闭事件会告诉你 wasClean 是假的?