当前位置: 首页 > news >正文

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

关闭浏览器后

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • AI 大模型重点行业应用情况
  • oppo手机精简包名列表
  • 贪心算法03(leetcode1005,134,135)
  • 一文学习yolov5 实例分割:从训练到部署
  • Spring RestClient报错:400 Bad Request : [no body]
  • CentOS7 配置Nginx域名HTTPS
  • React@16.x(23)useEffect
  • [ue5]建模场景学习笔记(5)——必修内容可交互的地形,交互沙(3)
  • Spring Boot 深度学习笔记:从入门到精通的全面指南
  • 【报文数据流中的反压处理】
  • CleanMyMac2024最新免费电脑Mac系统优化工具
  • SQL Server中的CTE和临时表优化
  • C语言 | Leetcode C语言题解之第140题单词拆分II
  • CMakeLists如何多行注释
  • 计算机毕业设计python+spark知识图谱音乐推荐系统 音乐数据分析可视化大屏 音乐爬虫 LSTM情感分析 大数据毕设 深度学习 机器学习
  • 【Linux系统编程】快速查找errno错误码信息
  • 【跃迁之路】【477天】刻意练习系列236(2018.05.28)
  • Android 初级面试者拾遗(前台界面篇)之 Activity 和 Fragment
  • Android框架之Volley
  • ComponentOne 2017 V2版本正式发布
  • Flex布局到底解决了什么问题
  • Linux CTF 逆向入门
  • Python中eval与exec的使用及区别
  • SpringCloud集成分布式事务LCN (一)
  • Traffic-Sign Detection and Classification in the Wild 论文笔记
  • tweak 支持第三方库
  • 大快搜索数据爬虫技术实例安装教学篇
  • 每天10道Java面试题,跟我走,offer有!
  • 面试总结JavaScript篇
  • 那些被忽略的 JavaScript 数组方法细节
  • 微信端页面使用-webkit-box和绝对定位时,元素上移的问题
  • 中文输入法与React文本输入框的问题与解决方案
  • 关于Android全面屏虚拟导航栏的适配总结
  • 完善智慧办公建设,小熊U租获京东数千万元A+轮融资 ...
  • 我们雇佣了一只大猴子...
  • ​​​​​​​​​​​​​​Γ函数
  • $HTTP_POST_VARS['']和$_POST['']的区别
  • (C++哈希表01)
  • (Java岗)秋招打卡!一本学历拿下美团、阿里、快手、米哈游offer
  • (补充)IDEA项目结构
  • (每日一问)计算机网络:浏览器输入一个地址到跳出网页这个过程中发生了哪些事情?(废话少说版)
  • (三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练
  • (四)汇编语言——简单程序
  • (一)pytest自动化测试框架之生成测试报告(mac系统)
  • (转)从零实现3D图像引擎:(8)参数化直线与3D平面函数库
  • (转)母版页和相对路径
  • (自适应手机端)响应式服装服饰外贸企业网站模板
  • .NET C# 使用 iText 生成PDF
  • .NET C#版本和.NET版本以及VS版本的对应关系
  • .NET 使用配置文件
  • .NET/C# 使窗口永不激活(No Activate 永不获得焦点)
  • .Net6 Api Swagger配置
  • .Net多线程Threading相关详解
  • .vollhavhelp-V-XXXXXXXX勒索病毒的最新威胁:如何恢复您的数据?
  • @data注解_一枚 架构师 也不会用的Lombok注解,相见恨晚