当服务器被杀死时,NodeJS socket.io-client不会触发'disconnect'或'close'事件 [英] NodeJS socket.io-client doesn't fire 'disconnect' or 'close' events when the server is killed

查看:3898
本文介绍了当服务器被杀死时,NodeJS socket.io-client不会触发'disconnect'或'close'事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个最小的例子。代码发布在这里: https://gist.github.com/1524725



我启动我的服务器,启动我的客户端,验证两者之间的连接是否成功,最后用CTRL + C终止服务器。当服务器死机时,客户机立即运行到完成并关闭,而不在on_client_close或on_client_disconnect中打印消息。没有可察觉的延迟。



从我做的读取,因为客户端进程正常终止,没有任何机会,STDOUT缓冲区不是可能还值得注意的是,当我杀死客户端而不是服务器时,服务器会按预期响应,触发on_ws_disconnect函数并从中删除客户端连接其活动客户端列表。



32位Ubuntu 11.10
Socket.io v0.8.7
Socket.io-client v0.8.7
NodeJS v0.6.0



谢谢!



--- EDIT ---



请注意,客户端和服务器都是Node.js进程,而不是传统的web浏览器客户端和node.js服务器。

解决方案

新答案



肯定是io-client的一个错误。 :(



我可以通过修改socket.io-client / libs / socket.js来解决这个问题。在433行,我简单地移动了 this.publish('disconnect',reason); 以上 if(wasConnected){


$ b b

  Socket.prototype.onDisconnect = function(reason){
var wasConnected = this.connected;

this.publish ,reason);

this.connected = false;
this.connecting = false;
this.open = false;

if(wasConnected) {
this.transport.close();
this.transport.clearTimeouts();


$ b b

按下ctrl + c后,断开连接消息大约会在十秒钟后触发。



旧讨论



要向客户端通知关闭事件,您需要向demo_server.js添加如下内容:

  var logger = io.log; 

process.on('uncaughtException',function(err){
if(io& io.socket){
io.socket.broadcast.send({type:'error',msg:err.toString(),stack:err.stack});
}
logger.error(err);
logger.error(err.stack);

// todo应该有一些默认的重置(重新启动服务器吗?)
app.close();
process.exit(-1);
});

process.on('SIGHUP',function(){
logger.error('Got SIGHUP signal。');
if(io& io.socket ){
io.socket.broadcast.send({type:'error',msg:'server disconnected with SIGHUP'});
}
// todo sighup上会发生什么? ?
// todo如果你使用upstart,只需调用restart节点demo_server.js
});

process.on('SIGTERM',function(){
logger.error('Shutting down。');
if(io& io.socket) {
io.socket.broadcast.send({type:'error',msg:'server disconnected with SIGTERM'});
}
app.close();
process.exit(-1);
});

当然,你在broadcast.send(...)



对于客户端,您可以使用on('disconnect',...)来判断服务器连接是否丢失。 。),你在你的例子中:

  client.on('disconnect',function(data){
alert('disconnect from server; reconnecting ...');
//等等...
});


I've written up a minimal example of this. The code is posted here: https://gist.github.com/1524725

I start my server, start my client, verify that the connection between the two is successful, and finally kill the server with CTRL+C. When the server dies, the client immediately runs to completion and closes without printing the message in either on_client_close or on_client_disconnect. There is no perceptible delay.

From the reading I've done, because the client process is terminating normally there isn't any chance that the STDOUT buffer isn't being flushed.

It may also be worth noting that when I kill the client instead of the server, the server responds as expected, firing the on_ws_disconnect function and removing the client connection from its list of active clients.

32-bit Ubuntu 11.10 Socket.io v0.8.7 Socket.io-client v0.8.7 NodeJS v0.6.0

Thanks!

--- EDIT ---

Please note that both the client and the server are Node.js processes rather than the conventional web browser client and node.js server.

解决方案

NEW ANSWER

Definitely a bug in io-client. :(

I was able to fix this by modifying socket.io-client/libs/socket.js. Around line 433, I simply moved the this.publish('disconnect', reason); above if (wasConnected) {.

Socket.prototype.onDisconnect = function (reason) {
    var wasConnected = this.connected;

    this.publish('disconnect', reason);

    this.connected = false;
    this.connecting = false;
    this.open = false;

    if (wasConnected) {
      this.transport.close();
      this.transport.clearTimeouts();

After pressing ctrl+c, the disconnect message fires in roughly ten seconds.

OLD DISCUSSION

To notify client of shutdown events, you would add something like this to demo_server.js:

var logger = io.log;

process.on('uncaughtException', function (err) {
  if( io && io.socket ) {
     io.socket.broadcast.send({type: 'error', msg: err.toString(), stack: err.stack});
  }
  logger.error(err);
  logger.error(err.stack);

  //todo should we have some default resetting (restart server?)
  app.close();
  process.exit(-1);
});

process.on('SIGHUP', function () {
  logger.error('Got SIGHUP signal.');
  if( io && io.socket ) {
     io.socket.broadcast.send({type: 'error', msg: 'server disconnected with SIGHUP'});
  }
  //todo what happens on a sighup??
  //todo if you're using upstart, just call restart node demo_server.js
});

process.on('SIGTERM', function() {
  logger.error('Shutting down.');
  if( io && io.socket ) {
     io.socket.broadcast.send({type: 'error', msg: 'server disconnected with SIGTERM'});
  }
  app.close();
  process.exit(-1);
});

Of course, what you send in the broadcast.send(...) (or even which command you use there) depends on your preference and client structure.

For the client side, you can tell if the server connection is lost using on('disconnect', ...), which you have in your example:

client.on('disconnect', function(data) {
   alert('disconnected from server; reconnecting...');
   // and so on...
});

这篇关于当服务器被杀死时,NodeJS socket.io-client不会触发'disconnect'或'close'事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆