为什么客户端在服务器接收到emit后断开连接并重新连接

Why is client disconnecting and reconnecting after server receives emit?

本文关键字:断开 连接 重新连接 emit 客户端 服务器 为什么      更新时间:2023-09-26

在我的socket.io应用程序(版本1.0.6)中,我有许多遵循相同模式的事件:

客户端发送带有数据的'some client emit',服务器接收'some client emit',在mongoose中保存一些对象,并发送带有解析数据的'some server emit'给其他客户端,并发送带有特定数据的单独'some server emit'给发送客户端。

例如,如果客户端代码包含:

...
console.log('emitting some client emit');
this.socket.emit('some client emit', {prop1: 'val1', prop2: 'val2'});
...
this.socket.on('some server emit', function(data){
   console.log('some server emit', data);
   if(data.doSomething){
      ...
   }
   ...
}
this.socket.on('error', function(err){
   console.log('error', err);
}
...

则服务器代码包括:

...
io.on('connection', function(socket){
   console.log(socket.id, 'connected');
   ... deal with connect 
   socket.on('disconnect', function(){
      console.log('socket', socket.id, 'disconnected');
      ... deal with disconnect
   }
   socket.on('some client emit', function(data){
      console.log('some client emit', data);
      var newThing = new Thing({
         prop1: data.prop1,
         prop2: data.prop2
      });
      newThing.save(function(err){ // a mongoose object
         if(err){
            console.log('error saving thing', err);
            socket.emit('error', err);
         } else {
            console.log('saving successful');
            socket.emit('some server emit', {thing: newThing, doSomething: true});
            for (var i = 0; i < someListOfSocketIds.length; i++)
                socket.broadcast.to(someListOfSocketIds[i]).emit('some server emit', {thing: newThing, doSomething: false});
         }
      }
      console.log('end of some client emit');
   }
}

我遇到的问题是客户端发出'some client emit',服务器获得事件并将'some server emit'发送到套接字id列表和发送客户端。所有客户端接收到emit BUT THEN ,原始发送客户端收到保存错误,断开连接并重新连接。

所以发送客户端的控制台是这样的:

 - emitting some client emit
 - some server emit {prop1: 'val1', prop2: 'val2', _id: <some guid>}
 - error {type: "TransportError", description: TypeError, stack: "Error: parser decode error
    at WS.Transport.onError (http://cdn.socket.io/socket.io-1.0.6.js:1:28005)
    at WS.Transport.onData (http://cdn.socket.io/socket.io-1.0.6.js:1:28768)",
    message: "parser decode error", ...}

服务器的控制台为:

 - *client-socket-id* connected
 - some client emit  {prop1: 'val1', prop2: 'val2'}
 - saving successful
 - end of some client emit
 - socket *client-socket-id* disconnected
 - *client-socket-id* connected

应该注意的是,newThing实际上确实进入了DB,其他客户端确实得到了它们的发出,并且在任何时候都没有运行服务器代码"console.log('error saving thing', err);"

所以问题是,如果有一个运行时错误,像比较一个变量的列表,而不是列表的长度,例如,

for (var i = 0; i < list; i++){ ...
}

或访问null变量的属性:

var thing;
if (thing.someNullPropery == ''){ ...
}

,在客户端的接收代码中:

 this.socket.on('some server emit', function(data){ ...
 }

则套接字立即断开连接,由于客户端仍在页面上,因此它随后连接导致断开/重新连接行为。我解决了我的问题,但如果其他人有这个问题,控制台日志无处不在!