SpringBoot——整合WebSocket长连接

目录

WebSocket

项目总结

 新建一个SpringBoot项目

pom.xml

WebSocketConfig配置类

TestWebSocketEndpoint服务端点类

socket.html客户端

IndexController控制器

SpringbootWebsocketApplication启动类

测试客户端和服务端如何使用WebSocket进行连接和通信


WebSocket

  • SpringBoot实现长连接时最常用的技术就是WebSocket
  • WebSocket是用在Web浏览器和服务器之间进行双向数据传输的一种协议,基于TCP
    • 在WebSocket中,只需要服务器和浏览器通过HTTP完成一个“握手”的动作,然后单独建立 一条TCP的通信通道即可进行数据的双向传送了。
    • 如果有一方想要关闭连接,则需要再完成一次“握手”通知对方,使得双方同步关闭
  • 避免服务器打开多个HTTP连接以节约资源,提高工作效率和资源利用率
  • 在SpringBoot项目中的使用:
    • 客户端需要在HTML页面上使用JavaScript创建WebSocket端点类的对象
    • 服务端需要使用SpringBoot提供的注解标注WebSocket端点类

项目总结

  1. 当客户端创建WebSocket端点类对象时,就是在尝试创建连接
  2. 如果连接被成功创建,则同时触发两端的打开连接事件
  3. 客户端的send()方法会触发服务端的发送消息事件
  4. 服务端通过远程端点对象发送消息会触发客户端的接收消息事件
  5. 不管是客户端关闭WebSocket端点类对象,还是服务端关闭Session对象,都会触发双方的关闭连接事件,导致连接被关闭

 新建一个SpringBoot项目

项目结构:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.12.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.study</groupId><artifactId>springboot_websocket</artifactId><version>0.0.1-SNAPSHOT</version><name>springboot_websocket</name><description>Demo project for Spring Boot</description><properties><java.version>8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId><version>2.4.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

WebSocketConfig配置类

package com.study.springboot_websocket.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;@Configuration
public class WebSocketConfig {@Beanpublic ServerEndpointExporter serverEndpointExporter(){return new ServerEndpointExporter();}
}

TestWebSocketEndpoint服务端点类

  • 一个服务端可以同时拥有多个WebSocket端点类,不同WebSocket端点类所映射的路径也不同
  • @ServerEndpoint
    • 该注解将该类标识为WebSocket端点类
    • 需要和@Component注解一起使用,让WebSocket端点类可以被SpringBoot注册
    • 完整路径是以"ws://"开头的,比如下列代码中,是"ws://localhost:8080/test"
    • 客户端使用该完整路径与服务端建立连接
  • Session对象:
    • 客户端每次与服务端建立连接后都会产生一个Session对象,Session对象可以存储一些由客户端传递给服务端的资料信息
    • 客户端只能使用一个Session对象,因为服务端可以连接多个客户端,所以服务端可以同时使用多个Session对象
  • WebSocket端点类可以捕捉4个事件:
    • 打开连接事件:@OnOpen
    • 发送消息事件:@OnMessage
    • 发生错误事件:@OnError
    • 关闭连接事件:@OnClose
    • 当发生某一个事件时可自行触发注解所标注的方法
  • WebSocket常见关闭状态码:
package com.study.springboot_websocket.websocket;import org.springframework.stereotype.Component;import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
/*** 服务器端点类*/@Component
@ServerEndpoint("/test")//设置端点的映射路径,将该类标识为WebSocket端点类
public class TestWebSocketEndpoint {@OnOpenpublic void onOpen(Session session)throws IOException {System.out.println(session.getId()+"客户端已连接");}/*** 当连接关闭时,在控制台打印关闭状态码*/@OnClosepublic void onClose(Session session, CloseReason reason){System.out.println(session.getId()+"客户端已关闭,关闭吗:"+reason.getCloseCode().getCode());}/*** 当服务端收到客户端发来的消息后,延迟500毫秒回复*/@OnMessagepublic void onMessage(String message,Session session){System.out.println("客户端发来消息:"+message);try {Thread.sleep(500);//休眠500毫秒} catch (InterruptedException e) {e.printStackTrace();}//getAsyncRemote:使用异步发送消息接口的对象向客户端发送消息session.getAsyncRemote().sendText("服务端收到客户端发来的消息:"+message);}/*** 打印异常*/@OnErrorpublic void onError(Session session,Throwable e){e.printStackTrace();//打印异常}
}

socket.html客户端

  • WebSocket客户端通常是网页浏览器,因此需要使用JavaScript予以实现
  • 须保证WebSocket端点类的对象映射的路径与服务端映射的路径相同
  • JavaScript的WebSocket端点类也可以捕捉4个事件:
    • 打开连接事件
    • 接收消息事件
    • 发生错误事件
    • 关闭连接事件
    • 这4个事件与服务器端点的4个事件具有相同的逻辑
  • WebSocket端点类的对象常用方法:
    • send():向服务端发送消息
    • close():正常关闭连接
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><script type="text/javascript">var websocket=null;var local=window.location;//当前页面的URL地址var url="ws://"+local.host+"/test";//长链接地址if("WebSocket" in window){websocket=new WebSocket(url);}else{alert("当前浏览器不支持长链接,请更换浏览器")}//连接发生错误触发的方法websocket.onerror=function () {document.getElementById("message").innerHTML+="<br/>发生错误";websocket.close();}//连接成功建立触发的方法websocket.onopen=function (event) {document.getElementById("message").innerHTML+="<br/>连接已创建";}//连接关闭触发的方法websocket.onclose=function () {document.getElementById("message").innerHTML+="<br/>连接已关闭";}//接收到消息触发的方法websocket.onmessage=function (event) {//将服务端发来的消息拼接到div中document.getElementById("message").innerHTML+="<br/>"+event.data;}//监听窗口关闭事件,当窗口关闭后要主动关闭websocket连接websocket.opbeforeunload=function () {websocket.close();}//单击按钮触发的方法function send() {var message=document.getElementById("text").value;//获取输入框中的文本websocket.send(message);//发送给服务端}</script>
</head>
<body><input type="text" id="text"><input type="button" id="btn" value="发送" onclick="send()"/><br/><div id="message"></div>
</body>
</html>

IndexController控制器

package com.study.springboot_websocket.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
public class IndexController {@RequestMapping("/index")public String index(){return "socket";//当用户访问"/index"地址时跳转到socket.html页面}
}

SpringbootWebsocketApplication启动类

package com.study.springboot_websocket;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class SpringbootWebsocketApplication {public static void main(String[] args) {SpringApplication.run(SpringbootWebsocketApplication.class, args);}}

测试客户端和服务端如何使用WebSocket进行连接和通信

运行启动类,访问网址:http://localhost:8080/index

关闭浏览器后

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/25173.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vscode 突然无法启动 WSL terminal 了怎么办?

参考&#xff1a;https://github.com/microsoft/vscode/issues/107485 根据参考网页&#xff0c;似乎在 windows 更新之后&#xff0c;重启&#xff0c;就有可能出现标题所说的 vscode 无法启动 WSL terminal 的情况。 首先使用 cmd 进入 wsl 终端&#xff0c;把 ~/.vscode-se…

(八)Mybatis持久化框架原理之不同Executor对比和Spring事务关系

文章目录 1. SqlSession的差异2. Executor的差异2.1 SimpleExecutor流程说明2.2 ReuseExecutor流程说明2.3 BatchExecutor流程说明 3. Mybatis事务4. Spring事务5. 总结 本篇文章主要是由一次批量插入数据而引起的思考与探究&#xff0c;在这篇文章中将会分析不同的Executor和S…

快来速领限量免费亚马逊云科技助理级架构师(SAA)和云从业者50%半价考试券

前几天在上海5/29的亚马逊云科技Summit峰会里&#xff0c;小李哥在现场分享了AWS 13张认证大满贯的心得&#xff08;图1&#xff09;&#xff0c;并且现场招募了自己的云师兄必过班(图2)。 本次必过班也为成员发放AWS SAA(助理级架构师)和云从业者(Cloud Practitioner)50%考试券…

AIGC作答《2024年高考作文|新课标I卷》能拿多少分?

AIGC作答《2024年高考作文&#xff5c;新课标I卷》能拿多少分&#xff1f; 一、前言二、题目三、作答 一、前言 如火如荼的2024年高考圆满落幕&#xff0c;在如此Happy的时刻&#xff0c;AIGC技术正以其前所未有的热度席卷全球。它不仅改变了我们获取信息的方式&#xff0c;也…

Element-UI入门

目录 1.什么是Element-UI 2.作用 3.版本历史 4.优缺点 4.1.优点 4.2.缺点 5.应用场景 6.代码示例 7.未来展望 8.总结 1.什么是Element-UI Element-UI 是由饿了么前端团队开发的一套基于 Vue.js 的桌面端组件库。提供了一整套 UI 组件&#xff0c;使开发者能够快速构…

一步一学!如何通过SOLIDWORKS曲面放样绘制花瓶?

SOLIDWORKS中&#xff0c;我们对放样凸台的操作已经非常熟悉。现在&#xff0c;我们将进一步探索曲面菜单栏中的放样成型功能。 1、绘制草图 首先&#xff0c;同普通放样凸台建模相同&#xff0c;绘制放样轮廓及引导线段。 可通过创建基准面布置轮廓&#xff0c;利用穿透选项将…

144、二叉树的前序递归遍历

题解&#xff1a; 递归书写三要素&#xff1a; 1&#xff09;确定递归函数的参数和返回值。要确定每次递归所要用到的参数以及需要返回的值 2&#xff09;确定终止条件。操作系统也是用栈的方式实现递归&#xff0c;那么如果不写终止条件或者终止条件写的不对&#xff0c;都…

前端调用接口有参数正常显示返回值,但是打印是undefined

前端调用接口有参数正常显示返回值&#xff0c;但是打印是undefined 这种有几种情况&#xff0c;但总的来说是因为我们做了接口拦截器的处理 一、后端返回code值有误 比如新来的后端忘记传code了。&#xff08;按照公司规范&#xff0c;一般都是200成功码&#xff09; 或者网上…

IO-源码阅读 glibc 2.35

文章目录 参考缓存机制IO_FILE_PLUSfopenfopen_internal_IO_no_init_IO_old_init _IO_new_file_init_internal_IO_link_in _IO_new_file_fopen_IO_file_open fread_IO_fread_IO_sgetn_IO_doallocbuf_IO_file_doallocate_IO_file_stat_IO_setb __underflow_IO_new_file_underflo…

[Cloud Networking] Layer 2

文章目录 1. 什么是Mac Address?2. 如何查找MAC地址&#xff1f;3. 二层数据交换4. [Layer 2 Protocol](https://blog.csdn.net/settingsun1225/article/details/139552315) 1. 什么是Mac Address? MAC 地址是计算机的唯一48位硬件编码&#xff0c;嵌入到网卡中。 MAC地址也…

英特尔:AI落地,未来已来

引言 随着AI技术的发展和大模型的普及&#xff0c;人工智能正在逐渐渗透到我们的日常生活中。2023年5月底&#xff0c;我参加了台北的英特尔技术展&#xff0c;深入了解了英特尔在AI个人电脑领域的最新进展。本文将详细介绍英特尔的新一代移动处理器Lunar Lake&#xff0c;以及…

LabVIEW 与组态软件在自动化系统中的应用比较与选择

LabVIEW 确实在非标单机设备、测试和测量系统中有着广泛的应用&#xff0c;特别是在科研、教育、实验室和小型自动化设备中表现突出。然而&#xff0c;LabVIEW 也具备一定的扩展能力&#xff0c;可以用于更复杂和大型的自动化系统。以下是对 LabVIEW 与组态软件在不同应用场景中…

【C++】——Stack与Queue(含优先队列(详细解读)

前言 之前数据结构中是栈和队列&#xff0c;我们分别用的顺序表和链表去实现的&#xff0c;但是对于这里的栈和队列来说&#xff0c;他们是一种容器&#xff0c;更准确来说是一种容器适配器 ✨什么是容器适配器&#xff1f; 从他们的模板参数可以看出&#xff0c;第二个参数模…

Kafka 架构

1 整体架构 1.1 Zookeeper Zookeeper 是一个分布式协调服务&#xff0c;用于管理 Kafka 的元数据。它负责维护 Kafka 集群的配置信息、Broker 列表和分区的 Leader 信息。 Zookeeper 确保了 Kafka 集群的高可用性和可靠性。 但 Zookeeper 已经成为 Kafka 性能瓶颈&#xff0c;…

SmartDraw Suite Edition 画图软件画表格内存示意图的使用方法

总述&#xff1a;遇到不会画的&#xff0c;比如如何画一条虚线&#xff0c;先将 虚线 翻译成英文&#xff0c;然后在 help 中查询。 新建的时候选择如下&#xff1a; 一、选择 Forms->Blank Form 二、画表格&#xff1a; 三、画箭头&#xff1a;先选择1在选择2 四、编辑文…

ASUS华硕ROG幻14Air笔记本GA403UI(UI UV UU UJ)工厂模式原厂Windows11系统安装包,带MyASUS in WinRE重置还原

适用型号&#xff1a;GA403UI、GA403UV、GA403UU、GA403UJ 链接&#xff1a;https://pan.baidu.com/s/1tz8PZbYKakfvUoXafQPLIg?pwd1mtc 提取码&#xff1a;1mtc 华硕原装WIN11系统工厂包带有ASUS RECOVERY恢复功能、自带面部识别,声卡,显卡,网卡,蓝牙等所有驱动、出厂主题…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 6月9日,星期日

每天一分钟&#xff0c;知晓天下事&#xff01; 2024年6月9日 星期日 农历五月初四 1、 人社部&#xff1a;个人养老金开户人数已超6000万&#xff0c;其中31岁至40岁的中高收入人群是开户、缴费和购买产品的主力军。 2、 医保局刊文&#xff1a;研究显示集采仿制药替代原研药…

VSC++: 民意调查比例法

void 民意调查比例法() {//缘由https://bbs.csdn.net/topics/396521294?page1#post-411408461从题目描述看&#xff1a;902/3~300.7&#xff0c;1498/5~299.6也就是大约求2个数的公约数&#xff0c;并使得这个公约数尽量求出最小误差&#xff1f;且商小于某值。int a 0, aa …

物理安全防护如何创新强化信息安全体系?

物理安全防护是信息安全体系的重要组成部分&#xff0c;它通过保护实体设施、设备和介质等&#xff0c;防止未授权访问、破坏、盗窃等行为&#xff0c;从而为信息系统提供基础的安全保障。要创新强化信息安全体系中的物理安全防护&#xff0c;可以从以下几个方面着手&#xff1…

VBA高级应用30例应用2实现在列表框内及列表框间实现数据拖动

《VBA高级应用30例》&#xff08;版权10178985&#xff09;&#xff0c;是我推出的第十套教程&#xff0c;教程是专门针对高级学员在学习VBA过程中提高路途上的案例展开&#xff0c;这套教程案例与理论结合&#xff0c;紧贴“实战”&#xff0c;并做“战术总结”&#xff0c;以…