背景
项目上有个新的需求,需要在系统数据发生改变时,前端页面要实时刷新页面数据。
简单的方案一:
最简单的方式就是直接在前端页面使用定时器定时刷新数据。
这个方案除非是定时的时间设置很短,否则还是会存在页面刷新不及时的情况。但是如果定时时间设置得过短,一旦客户端使用量变多,整个系统的请求数量会变的非常多,需要消耗许多服务器资源。故放弃这个方案。
方案二:
服务端推送的方式,通过使用Websocket,进入页面时,前端就与服务端建立起socket通道,当系统数据发生改变时,在服务端选中需要刷新的页面的socket会话,主动发送消息到前端,通知前端重新请求数据。
这个方案能达到实时刷新的需求,但考虑到的是客户端数量增长上来,建立的socket太多,会不会对占用太多的服务器资源。然后经过自己开发环境的简单测试,建立几千个socket对服务器资源消耗不大,就暂时决定用这个方案了。最终效果如何还是要 看生产环境的表现的。
实现
前端
前端使用的是vue框架
在methods中添加websocket相关函数
1 | javascript复制代码 data(){ |
在页面加载时调用函数建立socket连接
1 | javascript复制代码mounted() { |
在页面关闭或销毁时关闭socket
1 | javascript复制代码beforeDestroy() { |
后端
引入jar包
1 | java复制代码 <dependency> |
设置websocket配置类
1 | java复制代码 |
设置MyWebsocket
1 | java复制代码 |
由于socket的session是不支持序列化的,所以不能将session存在redis,在线上有多台服务器的情况下就无法共享session。
所以这里采用redis的消息订阅功能,当有一台服务器监听到系统数据发生变更,需要向前端发送消息时,会向redis发送消息,然后每台服务器的websocket那边会收到redis的 消息,检查自己拥有的session是否有满足相关条件的,若满足条件则向前端发送消息。
redis配置
redis消息监听
1 | java复制代码@Configuration |
redis消息接收接口
1 | java复制代码 |
在MyWebsocket中继承RedisMsg接口
1 | java复制代码public class MyWebsocket implements RedisMsg |
在MyWebsocket中实习RedisMsg接口的receiveMessage函数
1 | java复制代码 |
MyWebsocket类的完整代码
1 | java复制代码 |
业务场景下的使用
1 | java复制代码public class Test{ |
本文转载自: 掘金