热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Socket.io意外断开连接

如何解决《Socket.io意外断开连接》经验,为你挑选了1个好方法。

我有node.js服务和角度客户端使用socket.io在长时间的http请求期间传输一些消息.

服务:

export const socketArray: SocketIO.Socket[] = [];
export let socketMapping: {[socketId: string]: number} = {};

const socketRegister: hapi.Plugin = {
    register: (server) => {
        const io: SocketIO.Server = socket(server.listener);

        // Whenever a session connected to socket, create a socket object and add it to socket array
        io.on("connection", (socket) => {
            console.log(`socket ${socket.id} connected`);
            logger.info(`socket ${socket.id} connected`);

            // Only put socket object into array if init message received
            socket.on("init", msg => {
                logger.info(`socket ${socket.id} initialized`);
                socketArray.push(socket);
                socketMapping[socket.id] = msg;
            });

            // Remove socket object from socket array when disconnected
            socket.on("disconnect", (reason) => {
                console.log(`socket ${socket.id} disconnected because: ${reason}`)
                logger.info(`socket ${socket.id} disconnected because: ${reason}`);
                for(let i = 0; i  {
    try {
        // Add message to db here
        // await storeMessage(socketMapping[socketId], content);
        // Find corresponding socket and send message
        logger.info(`trying sending message to ${socketId}`);
        for (let i = 0; i 

客户:

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 方法.


推荐阅读
  • 使用nodejs爬取b站番剧数据,计算最佳追番推荐
    本文介绍了如何使用nodejs爬取b站番剧数据,并通过计算得出最佳追番推荐。通过调用相关接口获取番剧数据和评分数据,以及使用相应的算法进行计算。该方法可以帮助用户找到适合自己的番剧进行观看。 ... [详细]
  • 服务器上的操作系统有哪些,如何选择适合的操作系统?
    本文介绍了服务器上常见的操作系统,包括系统盘镜像、数据盘镜像和整机镜像的数量。同时,还介绍了共享镜像的限制和使用方法。此外,还提供了关于华为云服务的帮助中心,其中包括产品简介、价格说明、购买指南、用户指南、API参考、最佳实践、常见问题和视频帮助等技术文档。对于裸金属服务器的远程登录,本文介绍了使用密钥对登录的方法,并提供了部分操作系统配置示例。最后,还提到了SUSE云耀云服务器的特点和快速搭建方法。 ... [详细]
  • 本文讨论了在使用PHP cURL发送POST请求时,请求体在node.js中没有定义的问题。作者尝试了多种解决方案,但仍然无法解决该问题。同时提供了当前PHP代码示例。 ... [详细]
  • node.jsurlsearchparamsAPI哎哎哎 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
  • mac php错误日志配置方法及错误级别修改
    本文介绍了在mac环境下配置php错误日志的方法,包括修改php.ini文件和httpd.conf文件的操作步骤。同时还介绍了如何修改错误级别,以及相应的错误级别参考链接。 ... [详细]
  • iOS超签签名服务器搭建及其优劣势
    本文介绍了搭建iOS超签签名服务器的原因和优势,包括不掉签、用户可以直接安装不需要信任、体验好等。同时也提到了超签的劣势,即一个证书只能安装100个,成本较高。文章还详细介绍了超签的实现原理,包括用户请求服务器安装mobileconfig文件、服务器调用苹果接口添加udid等步骤。最后,还提到了生成mobileconfig文件和导出AppleWorldwideDeveloperRelationsCertificationAuthority证书的方法。 ... [详细]
  • 本文讨论了如何使用Web.Config进行自定义配置节的配置转换。作者提到,他将msbuild设置为详细模式,但转换却忽略了带有替换转换的自定义部分的存在。 ... [详细]
  • 【系列二】长连接,短连接及WebSocket介绍(含http1.0,1.1,2.0相关)
    前言上一节讲了长轮询和轮询及其实现,这节讲一讲长连接、短连接及webSocket,在讲这些之前,我们先来普及一下http相关的一 ... [详细]
  • node.js中需要遍历数组并返回值的处理实在是搞不懂了... ... [详细]
author-avatar
卜弃miao_286
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有