javascript - 分布式websocket,如何让命中不同服务器的人相互通信?
PHP中文网
PHP中文网 2017-04-11 12:38:00
[JavaScript讨论组]

最近接触到websocket,需求很简单,利用websocket让用户参与一个1v1的小游戏。
环境是分布式部署,且每台服务器是多进程,web服务器使用nodejs,websocket框架选用了socket.io。

遇到的问题:
首先,在单服务器调研,在利用nodejs多进程(cluster)时,建立websocket时会出现400报错,后来发现了是多进程的问题,用户访问服务器时不能保证每次访问到相同的进程中,所以后台会报错"Session ID unknown",可能是socket.io为了保证偶尔有可能会变成long polling,必须保证前后台要传递一个session id,但是每次页面刷新时,重新发起websocket应该和上次的刷新前的websocket没关系了才对,也有可能是socket.io为了保证与服务器重连节省资源才引入了session id,不知道我的理解对不对。
在网上查找了大量的资料,也看了socket.io官网的推荐方案(http://socket.io/docs/using-multiple-nodes/),有两种:

nginx
利用配置ip_hash让用户每次都连接到固定的进程,没玩过nginx不太懂。

redis
看了网上最多的既成的推荐方案也是redis,之前没有接触过redis,不知道其运行原理,大概了解之后,发现他是一个key-value的持久化存储,与MemCache、mongoDB类似,官网给出的代码示例:

var io = require('socket.io')(3000);
var redis = require('socket.io-redis');
io.adapter(redis({ host: 'localhost', port: 6379 }));

示例很简单,把请求弄一个适配器转向到连接redis服务,但是原理是什么样的呢,共享内存的方案吗,不太懂所以也没下手。

最后我选用了一个比较傻的方案,在不同的子进程中启动websocket服务时选用了不同的端口,比如一台服务器8核,会有8个端口3001-3008,这样用户连接某个固定端口时就不会再出现400error了,但是用户命中到不同的端口后,相互之间如何通信仍然是个问题,这只是单台服务器实验,如果是集群,相互通信也是一个问题,而且关键是否需要每次用户都连接到同一个端口和同一台服务器呢?说到底,还是对websocket了解太少了,希望能在这里得到一点指导和帮助。

PHP中文网
PHP中文网

认证高级PHP讲师

全部回复(3)
PHP中文网

如果是用 Redis, 我猜测是使用 Redis 的订阅/发布功能实现,这样就能很好的解决不同服务器上用户相互通信的问题。

ringa_lee

楼主你好最近我也在做websocket 分布式,但我做的是web站点的,用的框架是workerman ,也是多台服务器集群,
以下是我的理解:
如果我没没理解错误的话你的疑问应该就是不同服务器如何相互通信
我认为解决不同服务器通信在于共享数据,让每台websocket 接受到同样的数据,redis 的话就是内存共享。
抽象出来看的话每个进程如果需要通信,就是让他们接受的数据是一模一样的也就实现数据共享了websocket 只是负责传输数据而已。

具体的实现我也是推荐redis 。

题主这个问题解决的怎么样了?分享一下方案呗。

怪我咯

问题在于websocket session没办法序列化保存到redis,最近遇到同样的问题

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号