Java websocket+ nginx+redis负载均衡上实现单对单通讯
参考:https://www.jianshu.com/p/e25f7a48534d
由于公司项目需要用到websocket进行通讯,服务器采用负载均衡模式。由于WebSocketSession对象无法实例化的问题,导致无法使用Redis进行存储。如果一个用户连接进01主机,一个用户连接02主机,那么他们之间就无法实现单对单通讯,因为数据都保存在不同的Session域中。
思路(图片来自Java-websocket开发交流2群):
![](http://upload-images.jianshu.io/upload_images/6282395-a9173c921f33376c.png?imageMogr2/auto-orient/strip|imageView2/2/w/1051/format/webp)
![](http://upload-images.jianshu.io/upload_images/6282395-693406cc57cf7155.png?imageMogr2/auto-orient/strip|imageView2/2/w/878/format/webp)
![](http://upload-images.jianshu.io/upload_images/6282395-de1bd2d3d5b4df29.png?imageMogr2/auto-orient/strip|imageView2/2/w/719/format/webp)
![](http://upload-images.jianshu.io/upload_images/6282395-8253c1b066c37229.png?imageMogr2/auto-orient/strip|imageView2/2/w/866/format/webp)
1. 依照图中思路,实现不同主机登录的用户也能通讯。至于怎么实现握手的,百度一堆,这里就不讲了。
保存用户的session到集合中,并且把用户登录的服务器IP保存到Redis中。
![](http://upload-images.jianshu.io/upload_images/6282395-d08fecd4fe6b4ad2.png?imageMogr2/auto-orient/strip|imageView2/2/w/572/format/webp)
直接上代码
1. 先建一个UserSocket类,实现序列化接口
![](http://upload-images.jianshu.io/upload_images/6282395-80b51ddcaab0e13f.png?imageMogr2/auto-orient/strip|imageView2/2/w/797/format/webp)
2. 当用户握手成功时保存用户ID和本机IP到Redis并且用户的ID和WebSocketSession保存到全局变量中
![](http://upload-images.jianshu.io/upload_images/6282395-70c48f7c4654fe27.png?imageMogr2/auto-orient/strip|imageView2/2/w/782/format/webp)
![](http://upload-images.jianshu.io/upload_images/6282395-5f82656d2774ec93.png?imageMogr2/auto-orient/strip|imageView2/2/w/1085/format/webp)
3. Redis存储
新建一个RedisDao类
![](http://upload-images.jianshu.io/upload_images/6282395-084b20b820d26e7f.png?imageMogr2/auto-orient/strip|imageView2/2/w/1087/format/webp)
在spring-mybatis.xml中配置
![](http://upload-images.jianshu.io/upload_images/6282395-3acba6840eea59cc.png?imageMogr2/auto-orient/strip|imageView2/2/w/894/format/webp)
在RedisDao类中中创建函数存取对象到Redis中
![](http://upload-images.jianshu.io/upload_images/6282395-7c5c069fdfe3b804.png?imageMogr2/auto-orient/strip|imageView2/2/w/937/format/webp)
![](http://upload-images.jianshu.io/upload_images/6282395-8056cbe337292d96.png?imageMogr2/auto-orient/strip|imageView2/2/w/1028/format/webp)
新建一个序列化对象的类,
![](http://upload-images.jianshu.io/upload_images/6282395-9ab058d1861a3d51.png?imageMogr2/auto-orient/strip|imageView2/2/w/982/format/webp)
![](http://upload-images.jianshu.io/upload_images/6282395-d112e524b3c86d30.png?imageMogr2/auto-orient/strip|imageView2/2/w/930/format/webp)
4. 通过接口统一发送到指定用户
判断接收信息的用户是否在本IP中,如果不在同一个IP,转发给用户所在的IP接口处理
![](http://upload-images.jianshu.io/upload_images/6282395-2199fe696e7447ea.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp)
![](http://upload-images.jianshu.io/upload_images/6282395-2ae71e178188060d.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp)
![](http://upload-images.jianshu.io/upload_images/6282395-b26b41257a9bb7c5.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp)
5.Java post数据实现 (注意编码)
![](http://upload-images.jianshu.io/upload_images/6282395-eecfb8988f5af5f9.png?imageMogr2/auto-orient/strip|imageView2/2/w/1175/format/webp)
![](http://upload-images.jianshu.io/upload_images/6282395-83bfb0701f4cdd80.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp)
以上即可以实现不同主机中的用户相互通讯
由于该方法虽然能实现不同主机中的用户单对单聊天,但也有存在bug未处理。如果有更好的方式请通知我哈,一起交流交流。
作者:No刹那光辉
链接:https://www.jianshu.com/p/e25f7a48534d
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。