WebSocket服务端数据推送及心跳机制(Spring Boot + VUE)
一、WebSocket简介
HTML5规范在传统的web交互基础上为我们带来了众多的新特性,随着web技术被广泛用于web APP的开发,这些新特性得以推广和使用,而websocket作为一种新的web通信技术具有巨大意义。WebSocket是HTML5新增的协议,它的目的是在浏览器和服务器之间建立一个不受限的双向通信的通道,比如说,服务器可以在任意时刻发送消息给浏览器。支持双向通信。
二、WebSocket通信原理及机制
websocket是基于浏览器端的web技术,那么它的通信肯定少不了http,websocket本身虽然也是一种新的应用层协议,但是它也不能够脱离http而单独存在。具体来讲,我们在客户端构建一个websocket实例,并且为它绑定一个需要连接到的服务器地址,当客户端连接服务端的时候,会向服务端发送一个消息报文
三、WebSocket特点和优点
1、支持双向通信,实时性更强。
2、更好的二进制支持。
3、较少的控制开销。连接创建后,ws客户端、服务端进行数据交换时,协议控制的数据包头部较小。在不包含头部的情况下,服务端到客户端的包头只有2~10字节(取决于数据包长度),客户端到服务端的的话,需要加上额外的4字节的掩码。而HTTP协议每次通信都需要携带完整的头部。
4、支持扩展。ws协议定义了扩展,用户可以扩展协议,或者实现自定义的子协议。(比如支持自定义压缩算法等)
5、建立在tcp协议之上,服务端实现比较容易
6、数据格式比较轻量,性能开销小,通信效率高
7、和http协议有着良好的兼容性,默认端口是80和443,并且握手阶段采用HTTP协议,因此握手的时候不容易屏蔽,能通过各种的HTTP代理
四、WebSocket心跳机制
在使用websocket过程中,可能会出现网络断开的情况,比如信号不好,或者网络临时性关闭,这时候websocket的连接已经断开,而浏览器不会执行websocket 的 onclose方法,我们无法知道是否断开连接,也就无法进行重连操作。如果当前发送websocket数据到后端,一旦请求超时,onclose便会执行,这时候便可进行绑定好的重连操作。
心跳机制是每隔一段时间会向服务器发送一个数据包,告诉服务器自己还活着,同时客户端会确认服务器端是否还活着,如果还活着的话,就会回传一个数据包给客户端来确定服务器端也还活着,否则的话,有可能是网络断开连接了。需要重连~
五、在后端Spring Boot 和前端VUE中如何建立通信
1、在Spring Boot 中 pom.xml中添加 websocket依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2、创建 WebSocketConfig.java 开启websocket支持
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;/*** 开启WebSocket支持* */
@Configuration
public class WebSocketConfig {@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}}
3、创建 WebSocketServer.java 链接
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;@ServerEndpoint("/websocket/testsocket")
@Component
public class WebSocketServer {private static Logger log = LoggerFactory.getLogger(WebSocketServer.class);//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。private static int onlineCount = 0;//concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();//与某个客户端的连接会话,需要通过它来给客户端发送数据private Session session;/*** 连接建立成功调用的方法*/@OnOpenpublic void onOpen(Session session) {this.session = session;webSocketSet.add(this); //加入set中addOnlineCount(); //在线数加1log.info("有新窗口开始监听,当前在线人数为" + getOnlineCount());try {sendMessage("连接成功");} catch (Exception e) {log.error("websocket IO异常");}}/*** 连接关闭调用的方法*/@OnClosepublic void onClose(Session session) {try {webSocketSet.remove(this); //从set中删除subOnlineCount(); //在线数减1session.close();log.info("有一连接关闭!当前在线人数为" + getOnlineCount());} catch (IOException e) {e.printStackTrace();}}/*** 收到客户端消息后调用的方法** @param message 客户端发送过来的消息*/@OnMessagepublic void onMessage(String message, Session session) {log.info("收到的信息:"+message);Map<String, Object> maps = new HashMap<>();maps.put("type", message);this.sendInfo(maps);}/**** @param session* @param error*/@OnErrorpublic void onError(Session session, Throwable error) {log.error("发生错误");error.printStackTrace();}/*** 实现服务器主动推送*/public void sendMessage(Object obj) {try {synchronized (this.session) {this.session.getBasicRemote().sendText((JSON.toJSONString(obj)));}} catch (Exception e) {e.printStackTrace();}}/*** 群发自定义消息* */public static void sendInfo(Object obj) {for (WebSocketServer item : webSocketSet) {try {item.sendMessage(obj);} catch (Exception e) {continue;}}}public static synchronized int getOnlineCount() {return onlineCount;}public static synchronized void addOnlineCount() {WebSocketServer.onlineCount++;}public static synchronized void subOnlineCount() {WebSocketServer.onlineCount--;}
}
4、创建一个测试调用websocket发送消息 TimerSocketMessage.java (用定时器发送推送消息
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;import java.util.HashMap;
import java.util.Map;@Component
@EnableScheduling
public class TimerSocketMessage {/*** 推送消息到前台*/@Scheduled(cron = "*/5 * * * * * ")public void SocketMessage(){SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Map<String, Object> maps = new HashMap<>();maps.put("type", "sendMessage");maps.put("data", sdf.format(new Date()));WebSocketServer.sendInfo(maps);}
}
5、在VUE中创建和后端 websocket服务的连接并建立心跳机制。
<template><div><el-row :gutter="$ui.layout.gutter.g10"><el-col :span="$ui.layout.span.one" style="background-color: #FFFFFF; padding: 10px;"><el-form ref="form" :model="form" label-width="80px" size="small" :inline="true"><el-form-item label="生成数量"><el-input-number v-model="form.number" :min="1" :max="999" label="描述文字" /></el-form-item><el-form-item label="数值范围"><el-input-number v-model="form.start" :min="1" :max="9999999999" label="描述文字" /> ~<el-input-number v-model="form.end" :min="1" :max="9999999999" label="描述文字" /></el-form-item><el-form-item><el-button size="mini" type="primary" @click="spawn">生成</el-button></el-form-item></el-form></el-col></el-row><h1> websocket 消息推送测试:{{data}}</h1></div>
</template><script>
export default {name: 'Index',data() {return {form: {number: 1,start: 1,end: 100},data:0,timeout: 28 * 1000,//30秒一次心跳timeoutObj: null,//心跳心跳倒计时serverTimeoutObj: null,//心跳倒计时timeoutnum: null,//断开 重连倒计时websocket: null,}},created () {// 初始化websocketthis.initWebSocket()},methods: {spawn() {},initWebSocket () {let url = 'ws://localhost:8086/demo/websocket/testsocket'this.websocket = new WebSocket(url)// 连接错误this.websocket.onerror = this.setErrorMessage// 连接成功this.websocket.onopen = this.setOnopenMessage// 收到消息的回调this.websocket.onmessage = this.setOnmessageMessage// 连接关闭的回调this.websocket.onclose = this.setOncloseMessage// 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。window.onbeforeunload = this.onbeforeunload},reconnect () { // 重新连接if(this.lockReconnect) return;this.lockReconnect = true;//没连接上会一直重连,设置延迟避免请求过多this.timeoutnum && clearTimeout(this.timeoutnum);this.timeoutnum = setTimeout(() => {//新连接this.initWebSocket();this.lockReconnect = false;}, 5000);},reset () { // 重置心跳// 清除时间clearTimeout(this.timeoutObj);clearTimeout(this.serverTimeoutObj);// 重启心跳this.start();},start () { // 开启心跳this.timeoutObj && clearTimeout(this.timeoutObj);this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);this.timeoutObj = setTimeout(() => {// 这里发送一个心跳,后端收到后,返回一个心跳消息,if (this.websocket && this.websocket.readyState == 1) { // 如果连接正常this.websocketsend('heartbeat');} else { // 否则重连this.reconnect();}this.serverTimeoutObj = setTimeout(() => {//超时关闭this.websocket.close();}, this.timeout);}, this.timeout)},setOnmessageMessage (event) {let obj = JSON.parse(event.data);console.log("obj",obj)switch(obj.type) {case 'heartbeat'://收到服务器信息,心跳重置this.reset();break;case 'sendMessage':this.data = obj.dataconsole.log("接收到的服务器消息:",obj.data)}},setErrorMessage () {//重连this.reconnect();console.log("WebSocket连接发生错误" + ' 状态码:' + this.websocket.readyState)},setOnopenMessage () {//开启心跳this.start();console.log("WebSocket连接成功" + ' 状态码:' + this.websocket.readyState)},setOncloseMessage () {//重连this.reconnect();console.log( "WebSocket连接关闭" + ' 状态码:' + this.websocket.readyState)},onbeforeunload () {this.closeWebSocket();},//websocket发送消息websocketsend(messsage) {this.websocket.send(messsage)},closeWebSocket() { // 关闭websocketthis.websocket.close()},}
}
</script>
6、启动项目开始测试结果

7、vue文件连接websocket的url地址要拼接 context-path: /demo
相关文章:
WebSocket服务端数据推送及心跳机制(Spring Boot + VUE)
一、WebSocket简介 HTML5规范在传统的web交互基础上为我们带来了众多的新特性,随着web技术被广泛用于web APP的开发,这些新特性得以推广和使用,而websocket作为一种新的web通信技术具有巨大意义。WebSocket是HTML5新增的协议,它的…...
根据Dockerfile创建容器案例讲解
-f为dokerfile的路径, -t为新镜像的名称及版本。 后面这个点是寻址路径。...
CF 1328 D Carousel(环构造)
CF 1328 D. Carousel(环构造) Problem - D - Codeforces 大意:给出一个 n 个数组成的环 , 要对环上的点染色 , 要求任意一个相邻数不同的点对染色不同 ,求使用最少的颜色数 , 并用颜色数排列构造一种染色方案。 思路…...
什么是SaaS、PaaS、aPaaS、iPaaS、IaaS,一文讲透
在数字化的带动下,各行业对云服务的需求进入快速增长期。 SaaS、PaaS、aPaaS、iPaaS、IaaS…… 这些词经常出现,那么他们分别是什么意思?又有什么区别?小帆带大家一起来看看~ SaaS SaaS,Software as a Service&…...
Mac nvm 切换为淘宝镜像
编辑环境配置 # 或者 vim ~/.bash_profile $ vim ~/.zshrc贴入镜像 # 淘宝镜像 export NVM_NODEJS_ORG_MIRRORhttp://npm.taobao.org/mirrors/node export NVM_IOJS_ORG_MIRRORhttp://npm.taobao.org/mirrors/iojs# nvm环境配置 export NVM_DIR"$HOME/.nvm"[ -s &quo…...
aardio简单网站css或js下载练习
import win.ui; /*DSG{{*/ var winform win.form(text"下载网站css或js";right664;bottom290;maxfalse) winform.add( buttonClose{cls"button";text"退出";left348;top204;right498;bottom262;color14120960;fontLOGFONT(h-14);note" &qu…...
“维度削减+逻辑回归”:如何使用PCA大幅提升乳腺癌的预测成功率?
一、引言 乳腺癌是女性中最常见的恶性肿瘤之一,也影响着全球范围内许多人们的健康。据世界卫生组织(WHO)的数据,乳腺癌是全球癌症发病率和死亡率最高的肿瘤之一,其对个体和社会的危害不可忽视。因此,早期乳…...
Python程序设计基础:random库的使用
文章目录 一、常见的random库函数二、应用实例 一、常见的random库函数 在使用Python语言进行编程计算时,计算机完成的计算主要是确定的,但是在将其进行应用时,人们会模拟现实生活中的现象和活动,希望其增加一些随机性࿰…...
webpack 打包全流程
目录 1 webpack的安装 2 webpack的配置 配置流程: 1 webpack安装 2 创建webpack配置文件 webpack.config.js 3 配置入口 entry 单入口和多入口 2. 动态配置入口文件 4 配置出口 output 5 配置模式 mode(webpack4) 6 配置解析策略 …...
如何准备软件开发项目成本估算?
软件开发的成本估算是出了名的困难。对于软件开发项目来说,预算超支反而是常态,而不是例外。 在开始估算之前,请从业务角度了解项目的战略目标和你的目标。你可能计划尽可能赚取更多利润,探索新技术,或者在项目可能亏…...
音视频FAQ(三):音画不同步
摘要 本文介绍了音画不同步问题的五个因素:编码和封装阶段、网络传输阶段、播放器中的处理阶段、源内容产生的问题以及转码和编辑。针对这些因素,提出了相应的解决方案,如使用标准化工具、选择强大的传输协议、自适应缓冲等。此外࿰…...
MFC为控件添加背景图片
1、 添加选择Bitmap导入图片,图片文件最好放在项目res目录中,同时是BMP格式。上传后的图片在资源视图,命名为IDB_BITMAP_M_BACK。 2、在cpp的C***Dlg::OnPaint()函数下添加如下代码 void C***Dlg::OnPaint() {CPaintDC dc(this); // device…...
1047:判断能否被3,5,7整除
【题目描述】 给定一个整数,判断它能否被3,5,7整除,并输出以下信息: 1、能同时被3,5,7整除(直接输出3 5 7,每个数中间一个空格); 2、只能被其中两…...
十七、DoIP诊断通信 2 (专栏:从零开始搭建一个UDS诊断自动化测试CANoe工程)
专栏:从零开始搭建一个UDS诊断自动化测试CANoe工程 文章目录 专栏:从零开始搭建一个UDS诊断自动化测试CANoe工程前言一、以太网panel面板配置二、DoIP建立连接与断开连接三、panel面板上的DoIP诊断报文发送接收SEND按钮会话切换复位1101按钮解锁按钮DTC按钮3E80保持会话前言 …...
【2023】LeetCode HOT 100——哈希
目录 1. 两数之和1.1 C++实现1.2 Python实现1.3 时空分析2. 字母异位词分组2.1 C++实现2.2 Python实现2.3 时空分析3. 最长连续序列3.1 C++实现3.2 Python实现3.3 时空分析1. 两数之和 🔗 原题链接:1. 两数之和 不妨设 i...
TCP/IP---网络层
一、网络层的主要功能 1、提供了通讯过程中,必须要使用的另一个地址:逻辑IP地址【ipv4、ipv6】 2、连接不同媒介类型【内网--外网(intra -- inter)】 3、根据运行的不同的路由协议,选择不同的最佳路径 4、在选择的最好…...
解决访问Github出现的Couldn‘t connect to server错误
文章目录 前言原因分析以及解决办法原因分析解决办法 参考 前言 在Github上面克隆代码仓库出现Failed to connect to 127.0.0.1 port 1080 after 2063 ms: Couldnt connect to server、Failed to connect to github.com port 443 after 21083 ms: Couldnt connect to server等…...
善于打仗的人,没有特别大的名气和勇功
善于打仗的人,没有特别大的勇功 【安志强趣讲《孙子兵法》第15讲】 【原文】 见胜不过众人之所知,非善之善者也;战胜而天下曰善,非善之善者也。 【趣讲白话】 预判胜负没有超出常人的见识,算不上高明中最高明的&#x…...
虚幻官方项目《CropOut》技术解析 之 程序化岛屿生成器(IslandGenerator)
开个新坑详细分析一下虚幻官方发布的《CropOut》,文章会同步发布到我在知乎|CSDN的专栏里 文章目录 概要Create Island几何体生成部分随机种子Step 1Step 2Step 3Step 4Step 5Step 6 岛屿材质部分动态为草地设置颜色 程序设计的小技巧其它Platform Switch函数 概要 …...
微服务中间件--微服务保护
微服务保护 微服务保护a.sentinelb.sentinel限流规则1) 流控模式1.a) 关联模式1.b) 链路模式 2) 流控效果2.a) 预热模式2.b) 排队等待 3) 热点参数限流 c.隔离和降级1) Feign整合Sentinel2) 线程隔离2.a) 线程隔离(舱壁模式) 3) 熔断降级3.a) 熔断策略-慢…...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...
MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...
【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...
