热门标签 | 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 方法.


推荐阅读
  • Android系统源码分析Zygote和SystemServer启动过程详解
    本文详细解析了Android系统源码中Zygote和SystemServer的启动过程。首先介绍了系统framework层启动的内容,帮助理解四大组件的启动和管理过程。接着介绍了AMS、PMS等系统服务的作用和调用方式。然后详细分析了Zygote的启动过程,解释了Zygote在Android启动过程中的决定作用。最后通过时序图展示了整个过程。 ... [详细]
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • WebSocket与Socket.io的理解
    WebSocketprotocol是HTML5一种新的协议。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送 ... [详细]
  • 解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法
    本文介绍了解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法,包括检查location配置是否正确、pass_proxy是否需要加“/”等。同时,还介绍了修改nginx的error.log日志级别为debug,以便查看详细日志信息。 ... [详细]
  • 本文介绍了一个React Native新手在尝试将数据发布到服务器时遇到的问题,以及他的React Native代码和服务器端代码。他使用fetch方法将数据发送到服务器,但无法在服务器端读取/获取发布的数据。 ... [详细]
  • 使用eclipse创建一个Java项目的步骤
    本文介绍了使用eclipse创建一个Java项目的步骤,包括启动eclipse、选择New Project命令、在对话框中输入项目名称等。同时还介绍了Java Settings对话框中的一些选项,以及如何修改Java程序的输出目录。 ... [详细]
  • Ihaveaworkfolderdirectory.我有一个工作文件夹目录。holderDir.glob(*)>holder[ProjectOne, ... [详细]
  • 巧用arguments在Javascript的函数中有个名为arguments的类数组对象。它看起来是那么的诡异而且名不经传,但众多的Javascript库都使用着它强大的功能。所 ... [详细]
  • OrbitDBPeer 2 Peer Database using CRDTs
    2019独角兽企业重金招聘Python工程师标准Apeer-to-peerdatabaseforthedecentralizedwebOrbitDBisaserverless ... [详细]
  • 前端简史之纵横:Node东出
    引💡Ajax的出现,带来了jQuery时代,而jQuery时代也伴随着Node风暴淡淡退出了历史舞台。如果说Ajax给前端带来了从网页静 ... [详细]
  • 为了让用户体验更好,页面前端往往是通过ajax来进行数据处理;由于浏览器的设计原因每个域名下的连接有 ... [详细]
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社区 版权所有