vue+spring boot+websocket模拟服务端实时向前端推送数据

2023-11-17

一、后端
1、安装websocket依赖

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

2、配置websocket配置类

package com.iot.zmtestboot.websocketconfig;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

@Configuration
public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

3、配置websocket服务类

package com.sinoma.tj.realTimeMonitor.websocket;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;

@ServerEndpoint("/ws")
@Service
public class WebSocketServer {
	private static Logger log = LoggerFactory.getLogger(WebSocketServer.class);
	private static final AtomicInteger OnlineCount = new AtomicInteger(0);
	// concurrent包的线程安全Set,用来存放每个客户端对应的Session对象。
	private static CopyOnWriteArraySet<Session> SessionSet = new CopyOnWriteArraySet<Session>();



	/**
	 * 连接建立成功调用的方法
	 */
	@OnOpen
	public void onOpen(Session session) {
		SessionSet.add(session);
		int cnt = OnlineCount.incrementAndGet(); // 在线数加1
		log.info("有连接加入,当前连接数为:{}", cnt);
		//SendMessage(session, "收到消息,消息内容:");
	}

	/**
	 * 连接关闭调用的方法
	 */
	@OnClose
	public void onClose(Session session) {
		SessionSet.remove(session);
		int cnt = OnlineCount.decrementAndGet();
		log.info("有连接关闭,当前连接数为:{}", cnt);
	}

	/**
	 * 收到客户端消息后调用的方法
	 *
	 * @param message
	 *            客户端发送过来的消息
	 */
	@OnMessage
	public void onMessage(String message, Session session) {
		log.info("来自客户端的消息:{}",message);
		SendMessage(session, "收到消息,消息内容:"+message);
	}

	/**
	 * 出现错误
	 * @param session
	 * @param error
	 */
	@OnError
	public void onError(Session session, Throwable error) {
		log.error("发生错误:{},Session ID: {}",error.getMessage(),session.getId());
		error.printStackTrace();
	}

	/**
	 * 发送消息,实践表明,每次浏览器刷新,session会发生变化。
	 * @param session
	 * @param message
	 */
	public static void SendMessage(Session session, String message) {
		try {
			while (session.isOpen()){
				Date d = new Date();
				SimpleDateFormat sbf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				session.getBasicRemote().sendText(sbf.format(d));
				System.out.println("发送数据");
				System.out.println(sbf.format(d));
				Thread.sleep(1000);
			}
		} catch (IOException e) {
			log.error("发送消息出错:{}", e.getMessage());
			e.printStackTrace();
		}catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 群发消息
	 * @param message
	 * @throws IOException
	 */
//	public static void BroadCastInfo(String message) throws IOException {
//		for (Session session : SessionSet) {
//			if(session.isOpen()){
//				SendMessage(session, message);
//			}
//		}
//	}

	/**
	 * 指定Session发送消息
	 * @param sessionId
	 * @param message
	 * @throws IOException
	 */
//	public static void SendMessage(String message,String sessionId) throws IOException {
//		Session session = null;
//		for (Session s : SessionSet) {
//			if(s.getId().equals(sessionId)){
//				session = s;
//				break;
//			}
//		}
//		if(session!=null){
//			SendMessage(session, message);
//		}
//		else{
//			log.warn("没有找到你指定ID的会话:{}",sessionId);
//		}
//	}
}


4、如果启动报错javax.websocket.server.ServerContainer not available ,则修改依赖

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

二、前端部分

<template>
  <div>
    测试websocket<br />
    {{ recevieData }}
    <input type="button" value="打开socket" @click="initWebSocket" />
    <input type="button" value="关闭socket" @click="closewebsocket" />
    <!-- <input type="button" value="发送数据给java" @click="sendwebsocket" /> -->
  </div>
</template>

<script>
export default {
  name: "Home",
  data() {
    return {
      websock: null,
      recevieData: "",
    };
  },
  // created() {
  //   this.initWebSocket();
  // },
  destroyed() {
    // this.websocketsend("closeWebsocket");
    this.websock.close(); //离开路由之后断开websocket连接
  },
  methods: {
    // sendwebsocket() {
    //   //发送消息
    //   this.websocketsend("我是前端");
    // },
    closewebsocket() {
      this.websock.close(); //离开路由之后断开websocket连接
    },
    initWebSocket() {
      //初始化weosocket
      const wsuri = "ws://localhost:3310/ws";
      this.websock = new WebSocket(wsuri);
      this.websock.onmessage = this.websocketonmessage;
      this.websock.onopen = this.websocketonopen;
      this.websock.onerror = this.websocketonerror;
      this.websock.onclose = this.websocketclose;
    },
    websocketonopen() {
      //连接建立之后执行send方法发送数据
      let sendDataString = "连接数据";
      this.websocketsend(sendDataString);
    },
    websocketonerror() {
      //连接建立失败重连
      //this.initWebSocket();
    },
    websocketonmessage(e) {
      //数据接收
      console.log("数据接收");
      console.log(e.data);
      this.recevieData = e.data;
    },
    websocketsend(Data) {
      //数据发送
      this.websock.send(Data);
    },
    websocketclose(e) {
      //关闭
      console.log("断开连接", e);
    },
  },
};
</script>

三、如果导入pom依赖有问题,则选择自动适配

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
            <version>2.0.2.RELEASE</version>
        </dependency>

四、前后端互相通信
1、后端代码

package com.iot.zmtestboot.websocketconfig;

import org.springframework.stereotype.Service;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.CopyOnWriteArraySet;

@ServerEndpoint("/ws")
@Service
public class WebSocketServer {
    private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<>();
    // 与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;

    /**
     * 连接建立成功调用的方法*/
    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        webSocketSet.add(this);     // 加入set中
        System.out.println("连接成功");
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        webSocketSet.remove(this);  // 从set中删除
        System.out.println("关闭连接");
    }

    @OnMessage
    public void onMessage(String message,Session session) {
        System.out.println("来自客户端的消息:" + message);
//        System.out.println(session.isOpen());
//        System.out.println(session);
        // 群发消息
        //while (session.isOpen()){
//            System.out.println(this.session);
            for (WebSocketServer item : webSocketSet) {
                try {
                    Date d = new Date();
                    SimpleDateFormat sbf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    //System.out.println(sbf.format(d));
                    item.sendMessage(sbf.format(d));
                    Thread.sleep(1000);

                } catch (IOException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
      // }

    }

    /**
     * 发生错误时调用
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("发生错误");
        error.printStackTrace();
    }

    /**
     * 发送消息
     * @param message 客户端消息
     * @throws IOException
     */
    private void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }
}

2、前端代码

<template>
  <div>
    测试websocket<br />
    {{ recevieData }}
    <input type="button" value="打开socket" @click="initWebSocket" />
    <input type="button" value="关闭socket" @click="closewebsocket" />
    <!-- <input type="button" value="发送数据给java" @click="sendwebsocket" /> -->
  </div>
</template>

<script>
export default {
  name: "Home",
  data() {
    return {
      websock: null,
      recevieData: "",
    };
  },
  // created() {
  //   this.initWebSocket();
  // },
  destroyed() {
    this.websock.close(); //离开路由之后断开websocket连接
  },
  methods: {
    closewebsocket() {
      this.websock.close();
    },
    initWebSocket() {
      //初始化weosocket
      const wsuri = "ws://localhost:3310/ws";
      this.websock = new WebSocket(wsuri);
      this.websock.onmessage = this.websocketonmessage;
      this.websock.onopen = this.websocketonopen;
      this.websock.onerror = this.websocketonerror;
      this.websock.onclose = this.websocketclose;
    },
    websocketonopen() {
      //连接建立之后执行send方法发送数据
      this.websocketsend("connectSuccess");
    },
    websocketonerror() {
      //连接建立失败重连
      //this.initWebSocket();
      // handleErrors(e)
    },
    websocketonmessage(e) {
      //数据接收
      console.log("数据接收");
      console.log(e.data);
      this.recevieData = e.data;
      this.websocketsend("OK");
    },
    websocketsend(Data) {
      //数据发送
      this.websock.send(Data);
    },
    websocketclose(e) {
      //关闭
      console.log("断开连接", e);
      // this.websocketonerror();
    },
  },
};
</script>

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue+spring boot+websocket模拟服务端实时向前端推送数据 的相关文章

随机推荐

  • Mysql数据备份-定时自动备份dump备份命令

    登录数据库服务器并打开命令行工具 如Windows系统中的cmd exe 或图形化管理工具 如phpMyAdmin Navicat等 根据数据库类型 执行相应的备份命令 例如 MySQL数据库可以使用以下命令导出备份 mysqldump u
  • 数仓分层理论

    数据仓库 在实际工作中 数仓分层 元数据管理 数据质量管理一直是一个持续优化的过程 我们公司业务也是在持续的做数仓的优化工作 在数据治理这方面还是欠缺很多的经验的 下面先简单整理了一下第一个理论部分的相关笔记 数据仓库理论 数据仓库四大特征
  • 锐捷ap设置为路由模式_路由器AP、路由、桥接模式有什么区别【详细介绍】

    现在的路由大多数已经开始支持多种网络连接模式 那么我们就挑一款模式最全的路由来了解各种模式的区别吧 下文将以TP Link迷你无线路由器为例 在TP Link迷你无线路由器上一般有AP 接入点 模式 Router 无线路由 模式 Repea
  • stm32——EXTI

    EXTI 外部中断 是stm32的众多外设之一 属于中断的一种 它最重要的就是通过检测外部引脚口的电平变化 比如说上升沿 下降沿 以及双边沿 来触发中断 让主程序放下当前的事情 去执行发生中断时应该执行的事情 设置好的函数 大概是如上所属
  • SpringBoot集成OAuth2.0的四种授权方式

    背景 OAuth 开放授权 是一个开放标准 允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息 而不需要将用户名和密码提供给第三方应用或分享他们数据的所有内容 OAuth2 0 是OAuth协议的延续版本 但不向后兼容 OAuth
  • Numpy掩码数组masked arrays,这一篇就够了

    Numpy掩码数组masked arrays 这一篇就够了 1 什么是掩码数组 2 示例 2 1 一个例子走进掩码数组 2 2 创建一个数组第二个值是无效的 2 3 创建一个数组所有靠近1 e20的值是无效的 2 4 只获取有效项 2 5
  • 8647服务器装系统,机柜系统资料的.doc

    机柜系统资料的 机房冷通道 机柜系统分为节能系统 机柜 走线系统和配电系统 随着数据中心数据量的飞块速增长 数据中心的能耗量越来越高 主要由运行高功率的IT设备所致 且这些IT设备的密度还在不断提高 IT设备运行所产生大量的热 是数据中心所
  • MySql登录方法

    登录mysql u 用户名 p 用户对应密码 h 主机 socket IP地址 端口号 eg 192 168 10 113 3306 1 方法 mysql u root p密码 mysql u root p mysql hlocalhost
  • shineblink MPU6050六轴传感器测量物体姿态角

    MPU6050六轴传感器测量物体姿态角 一 姿态角 欧拉角 基本概念 二 代码实现功能描述 三 接线图 五 完整代码 六 代码运行结果 七 需要注意的地方 一 姿态角 欧拉角 基本概念 物体在空间中的姿态可以用欧拉角来定义 欧拉角包含pit
  • 数据分析——最小二乘法建立线性回归方程(最简单的一元线性模型为例)

    概述 别看公式多 其实很简单 最小二乘法其实又叫最小平方法 是一种数据拟合的优化技术 实质上是利用最小误差的平方寻求数据的最佳匹配函数 利用最小二乘法可以便捷的求得未知的数据 起到预测的作用 并且是的这些预测的数据与实际数据之间的误差平方和
  • Linux 异步 I/O 框架 io_uring:基本原理、程序示例与性能压测

    io uring是 2019 年 Linux 5 1内核首次引入的高性能异步 I O 框架 能显着加速 I O 密集型应用的性能 但如果你的应用已经在使用传统 Linux AIO 了 并且使用方式恰当 那io uring并不会带来太大的性能
  • 2023年最新Python安装详细教程

    目录 一 python官网 二 在官网的Downloads栏目 选择对应的操作系统 三 进入windows对应的页面 选择python版本 1 选择python的稳定发布版本Stable Releases 2 下载python的安装程序Wi
  • SO_RCVTIMEO超时errno

    首先打印一次recv调用失败的errno值和各个宏的值 由上可知 EAGIN和EWOULDBLOCK的值都是11 其实EAGIN是在setsockopt设置SO RCVTIMEO或SO SNDTIMEO后 recv或者send系列函数超时等
  • Centos 安装KVM并安装虚拟机

    需要注意的地方 如果修改了虚拟机XML配置 需要停止虚拟机 然后使用以下命令重新读取XML配置 virsh define etc libvirt qemu centos7 xml Linux服务器两块独立的网卡最好不要配置同一网段的IP地址
  • sam分类算法python代码_Python性能鸡汤_实践Sam

    Python性能鸡汤 一文见 http www oschina net question 1579 45822 下面是关于其中一些点 我的实践 1 内建函数 2 join 连接字符串 l aa bb mystring join l prin
  • 解决多个Tabs频繁切换造成数据错乱问题的方案

    一 利用axios的cancelToken import post from util ajax import axios from axios const CancelToken axios CancelToken post let ca
  • BUUCTF:[GXYCTF2019]BabyUpload1

    文件上传漏洞 不过这里我要吐槽一下 这个题首先他不允许传 png文件 再者 jpg文件不能大 打了也报错 传不上去 可想而知 我当时在做这个题的时候跟见了鬼一样难受 什么文件都传不了 接着做题吧 试着传一个PHP文件 告诉我不能传ph开头的
  • 全新中国交通标志检测数据集2021—CCTSDB 2021: A More Comprehensive Traffic SignDetection Benchmark(全新分类-多算法测评)

    CCTSDB 2021 重磅发布 全新数据集 全新分类 多种算法测评 欢迎大家使用 数据集发布网址 GitHub csust7zhangjm CCTSDB2021 论文原文 HCIS All Issue Human Centric Comp
  • 创建Access数据的ODBC数据源时没有Access数据源驱动器

    在作数据库实例的时候 实例2需要创建Access数据库的ODBC数据源 我的管理工具 ODBC数据源管理器里面只有SQL Server 没有Access等其他 当时我以为是装的时候少装了什么 于是就放下了 没有做这个实例 直接做下边的了 想
  • vue+spring boot+websocket模拟服务端实时向前端推送数据

    一 后端 1 安装websocket依赖