[eggjs/egg]eggsocket支持long-pulling的问题

2025-11-14 897 views
9

在项目中使用egg-socket进行信息推送,以socketio的transport:websocket作为主要的通信模式,transport:polling 作为降级方案,我们将一次websocket的连接加上socketid作为一次有效的前后端通信,每一次的API访问都会在这一个连接(socketid)上进行消息推送, 但是在使用polling的时候Socketio出现断连并重新连的问题,主要是连接通信的时候带的socketid改变了,我猜想这个socketid在polling的条件下egg-socket没有把socketid放入redis,导致每次请求又重新生成了一个socketid。请麻烦验证下是不是这个原因? (window as any).socket = io({ transports: ['polling'], });

复现步骤,错误日志以及相关配置

回答

1

你的这个工程运行的没问题啊。

2

@qingdengyue 你使用npm run dev 么?

6

@qingdengyue 你使用npm run dev 么?

是的,你升级一下你Node版本试试。

8

node 版本为 v10.14.2,可以稳定重现~

控制台中打印的 id 为进程 id,当 polling 请求到不同进程时,会发生 Session ID unknown 的报错。

@qingdengyue

5

复现不了~额~

6

看起来,你的 polling 请求都到一个 worker 进程,进程编号 164128,能不能确认下你是不是启动了两个 worker 进程?

参考:ps aux | grep egg-bin

另外,生产环境,多机部署情况下,很难保证每次 polling 请求到同一个进程,涉及到跨进程的情况,就会 Session ID unknown

3

@qingdengyue 在https域名上还是会出现polling连接失败的问题,http的域名不会出现这个问题, 请验证下?

1

@qingdengyue 都已经配置了sticky参数

0

1.HTTPS部署的启动命令是什么? 应该类似如下:

egg-scripts start --port=443 --https.key=F:\LZ\Source\egg-testcase\egg-socket-io-case\server.key --https.cert=F:\LZ\Source\egg-testcase\egg-socket-io-case\server.crt --sticky --title=egg-server-socket-io-case

2.HTTPS环境部署之后的日志发一下

正确启动后会有这么一句:

2019-05-23 11:58:11,459 INFO 6356 [master] egg started on https://127.0.0.1:443 (2668ms) with STICKY MODE!

3.egg-schedule 插件的插件名是schedule,不是egg-schedule。

7

@qingdengyue

  1. 我们这边没有用eggscript进行部署,用的是docker的自定义server.js启动的
8

1.哦~ 我贴的那个命令是,npm run start执行后对应的命令。Docker的server,js 也是用了egg的那个启动吧? 2.日志里看,HTTPS不是在Docker的server.js这边配置得?如果不是就得看,配置那边是怎么中转socket的了。

6

@qingdengyue

  1. 嗯是的
  2. HTTPS是在阿里云slb里配置的
9

这个SLB的HTTPS对WebSocket支持,我只找到一篇文档:SLB WebSocket FAQ, 已经不属于egg的范畴了,建议你在阿里云提工单。

4

@qingdengyue 为了验证不是阿里云的问题 我们在公司内部也部署了一套HTTPS,结果都一样的:直接访问ip socket连接没有问题;访问https域名socket连接连接失败...

6

使用Nginx 配置节参考:Socket Nginx ,跟上面你的复现仓库,放一起。提供HTTPS配置得。因为我本地始终复现不了。配置得部分比较多,所以建议你根据你们的环境提供一份复现。