在项目中使用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'], });
[eggjs/egg]eggsocket支持long-pulling的问题
回答
你的这个工程运行的没问题啊。
@qingdengyue 你使用npm run dev 么?
@qingdengyue 你使用npm run dev 么?
是的,你升级一下你Node版本试试。
node 版本为 v10.14.2,可以稳定重现~
控制台中打印的 id 为进程 id,当 polling 请求到不同进程时,会发生 Session ID unknown 的报错。
@qingdengyue
复现不了~额~
看起来,你的 polling 请求都到一个 worker 进程,进程编号 164128,能不能确认下你是不是启动了两个 worker 进程?
参考:ps aux | grep egg-bin
另外,生产环境,多机部署情况下,很难保证每次 polling 请求到同一个进程,涉及到跨进程的情况,就会 Session ID unknown
加上这个就可以了。
@qingdengyue 在https域名上还是会出现polling连接失败的问题,http的域名不会出现这个问题, 请验证下?
@qingdengyue 都已经配置了sticky参数
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。
@qingdengyue
- 我们这边没有用eggscript进行部署,用的是docker的自定义server.js启动的
1.哦~ 我贴的那个命令是,npm run start执行后对应的命令。Docker的server,js 也是用了egg的那个启动吧? 2.日志里看,HTTPS不是在Docker的server.js这边配置得?如果不是就得看,配置那边是怎么中转socket的了。
@qingdengyue
- 嗯是的
- HTTPS是在阿里云slb里配置的
这个SLB的HTTPS对WebSocket支持,我只找到一篇文档:SLB WebSocket FAQ, 已经不属于egg的范畴了,建议你在阿里云提工单。
@qingdengyue 为了验证不是阿里云的问题 我们在公司内部也部署了一套HTTPS,结果都一样的:直接访问ip socket连接没有问题;访问https域名socket连接连接失败...
使用Nginx 配置节参考:Socket Nginx ,跟上面你的复现仓库,放一起。提供HTTPS配置得。因为我本地始终复现不了。配置得部分比较多,所以建议你根据你们的环境提供一份复现。