服务器推送消息到前端实现页面数据实时刷新-分布式Websocket技术方案

服务器推送消息到前端实现页面数据实时刷新-分布式Vue+Websocket

背景

项目上有个新的需求,需要在系统数据发生改变时,前端页面要实时刷新页面数据。

简单的方案一:

  最简单的方式就是直接在前端页面使用定时器定时刷新数据。

  这个方案除非是定时的时间设置很短,否则还是会存在页面刷新不及时的情况。但是如果定时时间设置得过短,一旦客户端使用量变多,整个系统的请求数量会变的非常多,需要消耗许多服务器资源。故放弃这个方案。

方案二:

  服务端推送的方式,通过使用Websocket,进入页面时,前端就与服务端建立起socket通道,当系统数据发生改变时,在服务端选中需要刷新的页面的socket会话,主动发送消息到前端,通知前端重新请求数据。

  这个方案能达到实时刷新的需求,但考虑到的是客户端数量增长上来,建立的socket太多,会不会对占用太多的服务器资源。然后经过自己开发环境的简单测试,建立几千个socket对服务器资源消耗不大,就暂时决定用这个方案了。最终效果如何还是要 看生产环境的表现的。

实现

前端

前端使用的是vue框架

在methods中添加websocket相关函数

    data(){
   
        return {
   
            ws:null
        }
    },
    
    methods: {
   
     websocket() {
   
                //建立socket通道
                //process.env.VUE_APP_URL为服务端地址
                //code为自定义的参数,主要是用于服务端标识当前会话是哪个用户
                this.ws = new WebSocket(
                    'ws:' +
                        process.env.VUE_APP_URL +
                        '/websocket?identity=identity'
                );
                //socket连接成功后的回调函数
                this.ws.onopen = () => {
   
                    console.log('websocket连接成功!');
                    //若项目中没有使用nginx转发请求则忽略这步
                    //设置定时器,每过55秒传一次数据
                    //以防长时间不通信被nginx自动关闭会话
                    //也可以通过修改nginx配置文件延长关闭时间
                    setInterval(() => {
   
                        this.keepAlive(ws);
                    }, 55000);
                };
                //接收来自服务端消息的回调函数
                //fluseData() 为自定义的数据刷新函数
                this.ws.onmessage = evt => {
   
                    console.log('已接收来自后台的消息:', evt);
                    // 刷新数据
                    this.fluseData();
                };
                //关闭socket的回调函数
                this.ws.onclose = function() {
   
                    // 关闭 websocket
                    console.log('连接已关闭...');
                };
                // 路由跳转时结束websocket链接
                this.$router.afterEach(function() {
   
                    this.ws.close();
                });
            },
        //持续向后台发送消息,用于维护socket通道不被nginx关闭  
        keepAlive(webSocket) {
   
            if (webSocket) {
   
                if (webSocket.readyState == webSocket.OPEN) {
   
                    webSocket.send('');
                }
            }
        }
    }

在页面加载时调用函数建立socket连接

mounted() {
   
    this.websocket();
}

在页面关闭或销毁时关闭socket

beforeDestroy() {
   
        this.ws.close();
    },

后端

引入jar包

    <dependency>
		<groupId>org.apache.tomcat.embed</groupId>
		<artifactId>tomcat-embed-websocket</artifactId>
		<version>9.0.38</version>
	</dependency>

设置websocket配置类


@Configuration
public class MyWebsocketConfig implements ServerApplicationConfig {
   
    @Override
    public Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<? extends Endpoint>> set) {
   
        return null;
    }

    @Override
    public Set&
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值