上周知识星球中的使用实现式球友问了一个关于websocket的问题,大致如下
:

简单的消息概括一下:如果我们的项目是分布式环境 ,登录的队列用户被Nginx的反向代理分配到多个不同服务器
,那么在其中一个服务器建立了WebSocket连接的分布用户如何给在另外一个服务器上建立了WebSocket连接的用户发送消息呢?
今天就来解答一下球友的问题:其实 ,要解决这个问题就需要实现分布式WebSocket,免费模板使用实现式而分布式WebSocket一般可以通过以下两种方案来实现:
将消息(<用户id,消息消息内容>)统一推送到一个消息队列(Redis、队列Kafka等)的分布的topic
,然后每个应用节点都订阅这个topic,使用实现式在接收到WebSocket消息后取出这个消息的消息“消息接收者的用户ID/用户名” ,然后再比对自身是队列否存在相应用户的连接,如果存在则推送消息,分布否则丢弃接收到的亿华云使用实现式这个消息(这个消息接收者所在的应用节点会处理)在用户建立WebSocket连接后 ,使用Redis缓存记录用户的消息WebSocket建立在哪个应用节点上
,然后同样使用消息队列将消息推送到接收者所在的队列应用节点上面(实现上比方案一要复杂 ,但是网络流量会更低)实现方案下面将以第一种方案来具体实现,实现方式如下:
1. 定义一个WebSocket Channel枚举类 复制public enum WebSocketChannelEnum { // 测试使用的简易点对点聊天
CHAT("CHAT", "测试使用的简易点对点聊天", "/topic/reply"); WebSocketChannelEnum(String code, String description, String subscribeUrl) { this.code = code; this.description = description; this.subscribeUrl = subscribeUrl; } /** * 唯一CODE */ private String code; /** * 描述 */ private String description; /** * WebSocket客户端订阅的URL */ private String subscribeUrl; public String getCode() { return code; } public String getDescription() { return description; } public String getSubscribeUrl() { return subscribeUrl; } /** * 通过CODE查找枚举类 */ public static WebSocketChannelEnum fromCode(String code){ if(StringUtils.isNoneBlank(code)){ for(WebSocketChannelEnum channelEnum : values()){ if(channelEnum.code.equals(code)){ return channelEnum; } } } return null; }}1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.42.43.44.45.46.47.48.49.50.51. 2. 配置基于Redis的消息队列需要注意的是模板下载