客户:
connectSocket() {
if (!this.socket) {
try {
this.socket = io(socketUrl);
this.socket.emit('init', 'some-data');
} catch (err) {
console.log(err);
}
} else if (this.socket.disconnected) {
this.socket.connect();
this.socket.emit('init', 'some-data');
}
this.socket.on('some-channel', (data) => {
// Do something
});
this.socket.on('disconnect', (data) => {
console.log(data);
});
}
它们通常工作正常但随机产生断线错误.从我的日志文件中,我们可以看到:
2018-07-21T00:20:28.209Z[x]INFO: socket 8jBh7YC4A1btDTo_AAAN connected
2018-07-21T00:20:28.324Z[x]INFO: socket 8jBh7YC4A1btDTo_AAAN initialized
2018-07-21T00:21:48.314Z[x]INFO: socket 8jBh7YC4A1btDTo_AAAN disconnected because: ping timeout
2018-07-21T00:21:50.849Z[x]INFO: socket C6O7Vq38ygNiwGHcAAAO connected
2018-07-21T00:23:09.345Z[x]INFO: trying sending message to C6O7Vq38ygNiwGHcAAAO
在断开连接消息的同时,前端还注意到了一个断开事件transport close
.
从日志中我们可以得到工作流程如下:
前端启动套接字连接并向后端发送init消息.它还可以保存套接字.
后端检测到连接并收到init消息
后端将套接字放入阵列,以便随时随地使用
第一个套接字意外断开,另一个连接发布时没有前端的意识,所以前端从不发送消息来初始化它.
由于前端的已保存套接字未更改,因此在发出http请求时使用旧的套接字ID.结果,后端发送了带有旧套接字的消息,该套接字已从套接字数组中删除.
这种情况不会经常发生.有谁知道什么可能导致断开连接和未知的连接问题?
1> jfriend00..:
这真的取决于"长时间的http请求"正在做什么.node.js将您的Javascript作为单个线程运行.这意味着它一次只能做一件事.但是,由于服务器执行的很多事情都与I/O相关(从数据库读取,从文件中获取数据,从另一台服务器获取数据等),而node.js使用事件驱动的异步I/O,它通常可以同时在空中播放许多球,因此它似乎同时处理了大量请求.
但是,如果您的复杂http请求是CPU密集型的,使用大量的CPU,那么它占用了单个Javascript线程,并且在占用CPU时没有其他任何东西可以完成.这意味着所有传入的HTTP或socket.io请求都必须在队列中等待,直到一个node.js Javascript线程空闲,因此它可以从事件队列中获取下一个事件并开始处理该传入请求.
如果我们能够看到这个"非常复杂的http请求"的代码,我们只能更具体地帮助您.
在node.js中占用CPU的常用方法是将CPU密集型的东西卸载到其他进程.如果它主要是导致问题的这一段代码,你可以启动几个子进程(可能与服务器中的CPU数量一样多),然后向它们提供CPU密集型工作并离开主节点.js可以自由处理具有极低延迟的传入(非CPU密集型)请求.
如果您有多个可能占用CPU的操作,那么您必须将它们全部存储到子进程(可能通过某种工作队列),或者您可以部署群集.集群的挑战是给定的socket.io连接将是集群中的一个特定服务器,如果它恰好是执行CPU占用操作的那个进程,那么分配给该服务器的所有socket.io连接都将有很长的延迟.因此,对于此类问题,定期群集可能不太好.处理CPU密集型工作的工作队列和多个专用子进程可能更好,因为这些进程不会有任何负责的外部socket.io连接.
此外,您应该知道,如果您正在使用同步文件I/O,那将阻止整个node.js Javascript线程.node.js在同步文件I/O操作期间无法运行任何其他Javascript.node.js获得了它的可伸缩性,并且能够从异步I/O模型中同时运行许多操作.如果使用同步I/O,则完全打破了这一点并破坏了可伸缩性和响应性.
同步文件I/O仅属于服务器启动代码或单用途脚本(不是服务器).在服务器中处理请求时不应使用它.
使异步文件I/O更async/await
容易接受的fs
两种方法是使用流或使用promisified 方法.