springboot 整合websocket实现消息推送(nginx、vue)

摘要:
最近需要一个动态图表的功能,如下图。这种实现需要实时推送数据上来,那一般有两种方法方法一:前端写个定时器,不断轮询后台即可。这当然是很low的,请求太多很不友好,果断抛弃方法二:使用websocket,废话不多说直接上代码springboot整合websocket有两种方法,这里先记录原始方法:添加webSocket插件     ˂!

最近需要一个动态图表的功能,如下图。

springboot 整合websocket实现消息推送(nginx、vue)第1张

这种实现需要实时推送数据上来,那一般有两种方法

方法一:前端写个定时器,不断轮询后台即可。这当然是很low的,请求太多很不友好,果断抛弃

方法二:使用websocket,废话不多说直接上代码

springboot 整合websocket有两种方法,这里先记录原始方法:

添加webSocket插件

     <!--websocket-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>

WebSocketConfig配置

importorg.springframework.context.annotation.Bean;
importorg.springframework.context.annotation.Configuration;
importorg.springframework.web.socket.config.annotation.EnableWebSocket;
importorg.springframework.web.socket.server.standard.ServerEndpointExporter;
//注意注解
@EnableWebSocket
@Configuration
public classWebSocketConfig {
    @Bean
    publicServerEndpointExporter serverEndpointExporter() {
        return newServerEndpointExporter();
    }
}

然后写个webSocket工具类

importorg.springframework.stereotype.Controller;
importjavax.websocket.OnClose;
importjavax.websocket.OnMessage;
importjavax.websocket.OnOpen;
importjavax.websocket.Session;
importjavax.websocket.server.PathParam;
importjavax.websocket.server.ServerEndpoint;
importjava.util.ArrayList;
importjava.util.HashMap;
importjava.util.List;
importjava.util.Map;
importjava.util.concurrent.CopyOnWriteArraySet;
//注意是controller注解
@Controller
@ServerEndpoint("/websocket/{tableId}")
public classWebSocket {
    privateSession session;
public static CopyOnWriteArraySet<WebSocket> webSockets =new CopyOnWriteArraySet<>();
    private static Map<String,Session> sessionPool = new HashMap<String,Session>();

    @OnOpen
    public void onOpen(Session session, @PathParam(value="tableId")String code) {
        this.session =session;
        webSockets.add(this);
        sessionPool.put(code, session);
       //Constants.WEBSOCKET = true;//定义常量  是否开启websocket连接
        System.out.println("【websocket消息】有新的连接,总数为:"+webSockets.size());
    }

    @OnClose
    public voidonClose() {
        webSockets.remove(this);
        //Constants.WEBSOCKET = false;
        System.out.println("【websocket消息】连接断开,总数为:"+webSockets.size());
    }

    @OnMessage
    public voidonMessage(String message) {
        System.out.println("【websocket消息】收到客户端消息:"+message);
    }

    //此为广播消息
    public voidsendAllMessage(String message) {
        for(WebSocket webSocket : webSockets) {
            System.out.println("【websocket消息】广播消息:"+message);
            try{
                webSocket.session.getAsyncRemote().sendText(message);
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
    }

    //此为单点消息
    public voidsendOneMessage(String code, String message) {
        Session session =sessionPool.get(code);
        System.out.println(code);
        /*在发送数据之前先确认 session是否已经打开 使用session.isOpen() 为true 则发送消息
         * 不然会报错:The WebSocket session [0] has been closed and no method (apart from close()) may be called on a closed session */
        if (session != null &&session.isOpen()) {
            try{
                session.getAsyncRemote().sendText(message);
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
    }
}

简单的已经可以使用的,注意如果后台有用shiro权限框架的注意要开放接口

测试

下面介绍一种在线测试工具 http://ws.douqq.com/

springboot 整合websocket实现消息推送(nginx、vue)第2张

如果项目是前后端分离的,需要nginx进行请求转发的需要在nginx的配置文件里添加如下配置:红色字体部分

主要是把websocket的请求和http请求区分开

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;
    
   map $http_upgrade $connection_upgrade { 
         default upgrade;
         ''close;
        }

    server {
        listen       888;
        server_name  localhost;

    location ~/websocket/ {
        proxy_pass http://127.0.0.1:8089;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For     
        $proxy_add_x_forwarded_for;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
       }
           
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}    

这个时候接口换成nginx监听接口即可:

springboot 整合websocket实现消息推送(nginx、vue)第3张

待这些测试完之后在页面new一个websocket即可,我这里用的vue

created(){
this.initWebSocket();
},
destroyed(){
this.websocketclose();
},
initWebSocket: function () {
      //debugger;
      //WebSocket与普通的请求所用协议有所不同,ws等同于http,wss等同于https   key你自定义的key
      //var host = window.location.host
      this.websock = new WebSocket("ws://47.106.172.176:888/websocket/123");
      this.websock.onopen = this.websocketonopen;
      this.websock.onerror = this.websocketonerror;
      this.websock.onmessage = this.websocketonmessage;
      this.websock.onclose = this.websocketclose;
      console.log(this.websock);
      //this.websock.send("您好啊");
},
    websocketonopen: function () {
    },
    websocketonerror: function (e) {
    },
    websocketonmessage: function (e) {//JSON.parse(e.data); //这个是收到后端主动推送的值
},
    websocketclose: function (e) {
    },

如果想要后端不断推送数据上来,可以写个定时任务:

@Component
public classScheduledTask {
   
    @Autowired
    privateWebSocket webSocket;
    //添加定时任务
    //@Scheduled(cron = "0/5 * * * * ?")
    @Scheduled(fixedRate=2000)
    public voidsendMessage() {
        System.out.println("定时发送数据");
        //webSocket.sendAllMessage(JSON.toJSONString("str"));
//调用websocket推送消息
webSocket.sendOneMessage("1","str"); } }

免责声明:文章转载自《springboot 整合websocket实现消息推送(nginx、vue)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇2、设备树的规范(dts和dtb格式)DBeaver连接达梦数据库下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Flask之Sqlalchemy

Sqlalchemy 开发文档:https://www.jianshu.com/p/0ad18fdd7eed 创建数据库 安装 pip instal flask-sqlalchemy 两种配置方法 # 两种配置数据库方法 第一种app.config from flask import Flask import pymysql from flask_sq...

关于nginx upstream的几种配置方式

平时一直依赖硬件来作load blance,最近研究Nginx来做负载设备,记录下upstream的几种配置方式。 第一种:轮询 upstream test{     server 192.168.0.1:3000;     server 192.168.0.1:3001; } 第二种:权重 upstream test{     server 192.16...

Tengine环境安装

访问网址:http://tengine.taobao.org/download_cn.html下载需要的版本 第一步,解压   第二步、安装tegine 编译库 gcc, zlib1g-dev, libpcre3, libpcre3-dev这些库文件是必须的,会没办法编译tegine ubuntu安装命令:  apt-get install gcc lib...

vue2使用echarts markLine中的symbol引入png图片路径问题解决过程

在刚刚的开发中有个需求,需求是这样的:需要一条markLine标记线,标记线的顶端形状为实心箭头,且颜色和markLine标记线颜色不一致,这个箭头的方向会有一个接口返回的参数控制箭头在markLine标记线的首端还是末端, 如下图所示: 刚开始用的是echarts提供的默认配置(ECharts 提供的标记类型包括 'circle', 'rect', '...

vue,element列表大数据卡顿问题,vue列表渲染慢,element表格渲染慢,表格渲染慢(卡),表格全选卡,使用umy-ui

https://u-leo.github.io/umy-ui/docs/index.html https://github.com/u-leo/umy-ui ### umy-ui 一套为开发者准备的基于 Vue 2.0 的桌面端组件库,完美解决表格万级数据渲染卡顿,编辑表格卡顿问题 > umy-ui叫(U米-ui)或者叫悠米-ui > um...

vue 验证码

一、概述 效果图 二、代码实现 新建test目录,放2个vue文件。 sidentify.vue组件代码: <template> <div class="s-canvas"> <canvas id="s-canvas":width="contentWidth":height="contentHeight"&g...