由于公司项目需要用到websocket进行通讯,服务器采用负载均衡模式。由于WebSocketSession对象无法实例化的问题,导致无法使用Redis进行存储。如果一个用户连接进01主机,一个用户连接02主机,那么他们之间就无法实现单对单通讯,因为数据都保存在不同的Session域中。
思路(图片来自Java-websocket开发交流2群):
![](https://img.haomeiwen.com/i6282395/a9173c921f33376c.png)
![](https://img.haomeiwen.com/i6282395/693406cc57cf7155.png)
![](https://img.haomeiwen.com/i6282395/de1bd2d3d5b4df29.png)
![](https://img.haomeiwen.com/i6282395/8253c1b066c37229.png)
1. 依照图中思路,实现不同主机登录的用户也能通讯。至于怎么实现握手的,百度一堆,这里就不讲了。
保存用户的session到集合中,并且把用户登录的服务器IP保存到Redis中。
![](https://img.haomeiwen.com/i6282395/d08fecd4fe6b4ad2.png)
直接上代码
1. 先建一个UserSocket类,实现序列化接口
![](https://img.haomeiwen.com/i6282395/80b51ddcaab0e13f.png)
2. 当用户握手成功时保存用户ID和本机IP到Redis并且用户的ID和WebSocketSession保存到全局变量中
![](https://img.haomeiwen.com/i6282395/70c48f7c4654fe27.png)
![](https://img.haomeiwen.com/i6282395/5f82656d2774ec93.png)
3. Redis存储
新建一个RedisDao类
![](https://img.haomeiwen.com/i6282395/084b20b820d26e7f.png)
在spring-mybatis.xml中配置
![](https://img.haomeiwen.com/i6282395/3acba6840eea59cc.png)
在RedisDao类中中创建函数存取对象到Redis中
![](https://img.haomeiwen.com/i6282395/7c5c069fdfe3b804.png)
![](https://img.haomeiwen.com/i6282395/8056cbe337292d96.png)
新建一个序列化对象的类,
![](https://img.haomeiwen.com/i6282395/9ab058d1861a3d51.png)
![](https://img.haomeiwen.com/i6282395/d112e524b3c86d30.png)
4. 通过接口统一发送到指定用户
判断接收信息的用户是否在本IP中,如果不在同一个IP,转发给用户所在的IP接口处理
![](https://img.haomeiwen.com/i6282395/2199fe696e7447ea.png)
![](https://img.haomeiwen.com/i6282395/2ae71e178188060d.png)
![](https://img.haomeiwen.com/i6282395/b26b41257a9bb7c5.png)
5.Java post数据实现 (注意编码)
![](https://img.haomeiwen.com/i6282395/eecfb8988f5af5f9.png)
![](https://img.haomeiwen.com/i6282395/83bfb0701f4cdd80.png)
以上即可以实现不同主机中的用户相互通讯
由于该方法虽然能实现不同主机中的用户单对单聊天,但也有存在bug未处理。如果有更好的方式请通知我哈,一起交流交流。
.
网友评论