springboot整合websocket,入门学习

websocket

  • 1.简介
  • 2.常见的消息推送方式
    • 2.1轮询方式
      • 2.1.1短轮询
      • 2.1.2长轮询
    • 2.2 SSE(server-sent event):服务器发送事件
    • 2.3 websocket
  • 3.原理解析
  • 4.websocket API
    • 4.1客户端(浏览器)API
    • 4.2服务端API
  • 5.实现
    • 1.流程分析
    • 2.消息格式
    • 3.代码实现

1.简介

websocket是一种基于TCP连接上进行全双工通信的协议,设计用于提供低延迟全双工长期运行的连接,可以说websocket的出现就是解决实时通信的问题

全双工:通信的双方可以同时发送和接受数据,不需要等对方的响应或传输完成
半双方:允许数据在两个方向上传输,但是在同一个时间段只允许在一个方向上运输

实时通信:即时消息传递、音视频通话、在线会议和实时数据传输等,可以实现即时的数据传输和交流,不需要用户主动请求或刷新来获取更新数据

image.png

2.常见的消息推送方式

2.1轮询方式

2.1.1短轮询

浏览器以指定的时间间隔向服务器发出http请求,服务器实时返回数据给浏览器
image.png

数据有延迟并且对服务器的压力较大

2.1.2长轮询

浏览器发出ajax请求,服务器端接收到请求后,会阻塞请求直到有数据或者超时才会返回
image.png

相对于短轮询而言,对服务器的压力会小一点

2.2 SSE(server-sent event):服务器发送事件

  • SSE在服务器和客户端之间打开一个单向通道
  • 服务端响应的不再是一次性的数据包,而是text/event-stream类型的数据流信息
  • 服务器有数据变更时将数据流式传输到客户端

image.png

2.3 websocket

看本篇

3.原理解析

image.png

  • 浏览器发送请求,请求头中有UPgrade:websocket,请求将http协议升级为websocket协议
  • 服务器响应,响应状态码为101,表示将将http协议升级为websocket协议
  • 握手后就可以双向数据传输

image.png

4.websocket API

4.1客户端(浏览器)API

(1)websocket对象创建

let ws = new WebSocket(URL);

URL说明:

  • 格式:协议://ip地址/访问路径,默认端口为80
  • 协议:协议名称为ws

(2)websocket对象相关事件
image.png

(3)websocket对象提供的方法
image.png

总体结构
image.png

4.2服务端API

Tomcat的7.0.5 版本开始支持WebSocket,并且实现了Java WebSocket规范
Java WebSocket应用由一系列的Endpoint组成,Endpoint 是一个java对象,代表WebSocket链接的一端,对于服务端,我们可以视为处理具体WebSocket消息的接口。
可以通过两种方式定义Endpoint:

  • 第一种是编程式,即继承类javax.websocket.Endpoint并实现其方式
  • 第二种是注解式,即定义一个POJO,并添加@ServerEndpoint相关注解

Endpoint实例在WebSocket握手时创建,并在客户端与服务端链接过程中有效,最后在链接关闭时结束。在Endpoint接口中明确定义了与其生命周期相关的方法,规范实现者确保生命周期的各个阶段调用实例的相关方法。生命周期方法如下:
image.png

左边是编程式,右边是注解式

image.png

服务端如何接收客户端发送的数据呢?

  • 编程式:通过添加MessageHandler消息处理器来接收消息
  • 注解式:在定义Endpoint时,通过@OnMessage竹节指定接收消息的方法

服务端如何推送数据给客户端呢?
发送消息则由RemoteEndpoint完成,它的实例由Session(会话)维护,websocket连接成功后就建立了会话。
发送消息有2种方式发送消息:

  • 通过session.getBasicRemote获取同步消息发送的实例,然后调用其sendXxx()发送消息,如sendText()方法向客户端发送文本消息
  • 通过session.getAsyncRemote获取异步消息发送的实例,然后调用其sendXxx()发送消息…

5.实现

1.流程分析

image.png

  • 登录完成后发送请求转为websocket协议,记录session,并广播消息,向所有客户端响应用户列表消息,显示用户在线列表
  • 客户端发送消息后服务端解析消息,并判断收消息的人,将消息推送给指定的客户端
  • 关闭连接,向所有客户端响应用户列表消息,显示用户在线列表

2.消息格式

客户端—>服务端

image.png
toName:谁接收消息

服务端—>客户端

image.png
system:判断是否为系统消息
fromName:谁发送的消息
message:消息内容

系统消息中的李四王五是在线用户列表

3.代码实现

(1)引入依赖

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

(2)编写配置类,扫描添加有@ServerEndpoint注解的 Bean

@Configuration
public class WebsocketConfig {@Beanpublic ServerEndpointExporter endpointExporter(){return new ServerEndpointExporter();}
}

ServerEndpointExporter是一个Spring Boot提供的用于自动注册和管理WebSocket端点的类。通过将ServerEndpointExporter作为Bean定义在配置类中,Spring Boot会自动扫描并注册所有带有@ServerEndpoint注解的WebSocket端点。

(3)编写配置类,用于获取 HttpSession 对象

@Configuration
public class GetHttpSessionConfig extends ServerEndpointConfig.Configurator {@Overridepublic void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {//获取httpSession对象HttpSession httpSession = (HttpSession) request.getHttpSession();//将httpsession对象保存起来sec.getUserProperties().put(HttpSession.class.getName(), httpSession);}
}

修改握手请求,在这个方法中,我们可以获取到HTTP请求的会话对象(HttpSession),并将其保存起来,以便后续在WebSocket连接中使用。

ServerEndpointConfig是Java WebSocket API中的一个接口,用于配置WebSocket端点的相关参数和属性,通过getUserProperties方法获取到用户属性,并使用put方法将HttpSession对象存储在其中。

(4)编写Endpoint类

//定义的endpoint类
@ServerEndpoint(value = "/chat",configurator = GetHttpSessionConfig.class)//前端中写的访问websocket的路径
@Component
public class ChatEndpoint {//每个用户都会创建一个Endpoint对象,创建一个公用的map集合来存sessionprivate static final Map<String, Session> onlineUsers = new ConcurrentHashMap<>();private HttpSession httpSession;/*** 建立连接后时被调用* @param session* @param config*/@OnOpenpublic void onOpen(Session session, EndpointConfig config){//1.将session进行保存httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());String username = (String) httpSession.getAttribute("user");onlineUsers.put(username,session);//2.广播消息,需要将登录的所有用户推送给所有用户String message = MessageUtils.getMessage(true, null, getFriends());//使用MessageUtils中的方法broadcastAllUsers(message);}//获取onlineUsers的map集合中的键private Set getFriends() {Set<String> set = onlineUsers.keySet();return set;}//广播给所有用户private void broadcastAllUsers(String message){try {//遍历map集合Set<Map.Entry<String, Session>> entries = onlineUsers.entrySet();for (Map.Entry<String, Session> entry : entries) {//获取所有用户对应的session对象Session session = entry.getValue();//发送同步消息session.getBasicRemote().sendText(message);}} catch (IOException e) {//记录日志}}/*** 浏览器发送消息到服务端时被调用* 将消息推送给指定的用户* @param message*/@OnMessagepublic void onMessage(String message){try {//将消息的json字符串转换为消息的对象Message msg = JSON.parseObject(message, Message.class);//获取消息接收方的用户名String toName = msg.getToName();String msgString = msg.getMessage();//获取消息接收方的sessionSession session = onlineUsers.get(toName);//获取消息发送方的用户名String fromName = (String) httpSession.getAttribute("user");//将消息字符串转换为指定的json格式String msgJson = MessageUtils.getMessage(false, fromName, msgString);//发送消息给指定的用户session.getBasicRemote().sendText(msgJson);} catch (IOException e) {//记录日志}}/*** 关闭连接时被调用* @param session*/@OnClosepublic void onClose(Session session){//1.从onlineUsers中剔除该用户的sessionString username = (String) httpSession.getAttribute("user");onlineUsers.remove(username);//2.广播给所有用户,该用户下线了//将消息字符串转换为指定的json格式String message = MessageUtils.getMessage(true, null, getFriends());broadcastAllUsers(message);}
}

消息工具类

public class MessageUtils {public static String getMessage(boolean isSystemMessage,String fromName, Object message) {ResultMessage result = new ResultMessage();result.setSystem(isSystemMessage);result.setMessage(message);if(fromName != null) {result.setFromName(fromName);}return JSON.toJSONString(result);}
}
  1. @ServerEndpoint注解被标注在ChatEndpoint类上,表示该类是一个WebSocket端点。value = "/chat"指定了WebSocket端点的URL路径为/chat,即客户端可以通过ws://localhost:8080/chat来连接到该WebSocket端点;configurator = GetHttpSessionConfig.class指定了一个配置器类GetHttpSessionConfig,用于在WebSocket握手过程中获取和保存HttpSession对象
  2. value = "/chat"指定了WebSocket端点的URL路径为/chat,即客户端可以通过ws://localhost:8080/chat来连接到该WebSocket端点;configurator = GetHttpSessionConfig.class指定了一个配置器类GetHttpSessionConfig,用于在WebSocket握手过程中获取和保存HttpSession对象
  3. onlineUsers用来创建一个公用的map集合来存所有已登录用户的session,因为每个用户登录后都会创建一个Endpoint对象。
  4. 在session.getBasicRemote().sendText()发送消息之前需要将消息字符串转化为指定的json格式

image.png
image.png
/(ㄒoㄒ)/~~

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

如何用好应用权限,保护隐私数据?银河麒麟桌面操作系统V10 SP1 2303 update2新功能解析

为您介绍银河麒麟桌面操作系统V10 SP1 2303 update2隐私设置和权限管理功能&#xff0c;为您的个人数据安全保驾护航。 说到个人数据隐私&#xff0c;在科技重塑生活本质的数字世界&#xff0c;个人信息遭受持续威胁。2018年&#xff0c;某国际知名社交平台因安全系统漏洞而遭…

OpenAI划时代大模型——文本生成视频模型Sora作品欣赏(八)

Sora介绍 Sora是一个能以文本描述生成视频的人工智能模型&#xff0c;由美国人工智能研究机构OpenAI开发。 Sora这一名称源于日文“空”&#xff08;そら sora&#xff09;&#xff0c;即天空之意&#xff0c;以示其无限的创造潜力。其背后的技术是在OpenAI的文本到图像生成模…

docker 容器修改端口和目录映射

容器修改端口映射 一般在运行容器时&#xff0c;我们都会通过参数 -p&#xff08;使用大写的-P参数则会随机选择宿主机的一个端口进行映射&#xff09;来指定宿主机和容器端口的映射&#xff0c;例如 docker run -it -d --name [container-name] -p 8088:80 [image-name]这里…

数据结构:循环队列

一、队列的概念 操作受限的线性表&#xff0c;允许在队列的一端执行入队操作&#xff0c;另一端执行出队操作 先进先出(FIFO) 1.顺序队列 物理结构连续&#xff0c;依赖于数组实现 队列中有一个队头指针和队尾指针&#xff0c;队头指针保存每次要出队的元素&#xff0c;队…

网站三合一缩略图片介绍展示源码

网站三合一缩略图片介绍展示源码&#xff0c;PHP源码&#xff0c;运行需要php环境支持&#xff0c;效果截图如下 蓝奏云下载&#xff1a;https://wfr.lanzout.com/ihY8y1pgim6j

Springboot+vue的考务报名平台(有报告)。Javaee项目,springboot vue前后端分离项目。

演示视频&#xff1a; Springbootvue的考务报名平台&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot vue前后端分离项目。 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的考务报名平台&#xff0c;采用M&#xff08;model&#xff0…

新加坡服务器托管:开启全球化发展之门

新加坡作为一个小国家&#xff0c;却在全球范围内享有极高的声誉。新加坡作为亚洲的科技中心&#xff0c;拥有先进的通信基础设施和成熟的机房托管市场。除了其独特的地理位置和发达的经济体系外&#xff0c;新加坡还以其开放的商业环境和便利的托管服务吸引着越来越多的国际公…

Python手册(Machine Learning)--LightGBM

Overview LightGBM&#xff08;Light Gradient Boosting Machine&#xff09;是一种高效的 Gradient Boosting 算法&#xff0c; 主要用于解决GBDT在海量数据中遇到的问题&#xff0c;以便更好更快的用于工业实践中。 数据结构说明lightgbm.DatasetLightGBM数据集lightgbm.Bo…

【前端素材】推荐优质后台管理系统Salreo平台模板(附源码)

一、需求分析 当我们从多个层次来详细分析后台管理系统时&#xff0c;可以将其功能和定义进一步细分&#xff0c;以便更好地理解其在不同方面的作用和实际运作。 1. 结构层次 在结构层次上&#xff0c;后台管理系统可以分为以下几个部分&#xff1a; a. 辅助功能模块&#…

项目分享|基于ELF 1开发板的车牌识别系统

该项目选用ElfBoard ELF 1开发板作为核心硬件平台&#xff0c;利用USB接口连接的摄像头捕捉并识别车牌信息。一旦车牌成功识别&#xff0c;系统会触发绿灯指示&#xff0c;并将识别所得的车牌号码实时传输至手机APP。车牌识别技术方面&#xff0c;借助了百度提供的OCR&#xff…

Java+SpringBoot+Vue+MySQL:狱内罪犯危险性评估系统全栈开发

✍✍计算机毕业编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java、…

postman访问k8s api

第一种方式&#xff1a; kubectl -n kubesphere-system get sa kubesphere -oyaml apiVersion: v1 kind: ServiceAccount metadata:annotations:meta.helm.sh/release-name: ks-coremeta.helm.sh/release-namespace: kubesphere-systemcreationTimestamp: "2023-07-24T07…

vue2后台管理系统demo,包含增删查改、模糊搜索、分页

因一直敲小程序&#xff0c;vue不熟练&#xff0c;自己练手项目&#xff0c;就包含增删查改以及模糊搜索分页 一、页面简单但功能齐全 二、数据是mock模拟 三、启动步骤 1、 json-server --watch data.json 启动mock数据 2、npm i 下载依赖 3、npm run serve 四、github地址…

最新IE跳转Edge浏览器解决办法(2024.2.26)

最新IE跳转Edge浏览器解决办法&#xff08;2024.2.26&#xff09; 1. IE跳转原因1.1. 原先解决办法1.2. 最新解决办法1.3. 最后 1. IE跳转原因 关于IE跳转问题是由于在2023年2月14日&#xff0c;微软正式告别IE浏览器&#xff0c;导致很多使用Windows10系统的电脑在打开IE浏览…

PHP请求示例获取淘宝商品详情数据API接口(按关键词搜索商品列表)

请求示例&#xff0c;API接口接入Anzexi58 item_get-获得淘宝商品详情 taobao.item_get 公共参数 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥WeChat18305163218api_nameString是API接口名称&#xff08;包…

存储卡0字节危机:原因解析与数据拯救之道

存储卡0字节现象揭秘 在数字时代&#xff0c;存储卡作为我们存储重要数据的主要工具之一&#xff0c;一旦遭遇“0字节”的困境&#xff0c;无疑是一场数据灾难。所谓存储卡0字节&#xff0c;即存储卡的文件系统显示容量为0&#xff0c;所有文件仿佛凭空消失&#xff0c;用户无…

Ubuntu服务器fail2ban的使用

作用&#xff1a;限制ssh远程登录&#xff0c;防止被人爆破服务器&#xff0c;封禁登录ip 使用lastb命令可查看到登录失败的用户及ip&#xff0c;无时无刻的不在爆破服务器 目录 一、安装fail2ban 二&#xff0c;配置fail2ban封禁ip的规则 1&#xff0c;进入目录并创建ssh…

在TMP中计算书名号《》高度的问题

1&#xff09;在TMP中计算书名号《》高度的问题 2&#xff09;FMOD设置中关于Virtual Channel Count&Real Channel Count的参数疑问 3&#xff09;Unity 2021.3.18f1 ParticleSystemTrailGeometryJob粒子拖尾系统崩溃 4&#xff09;XLua打包Lua文件粒度问题 这是第375篇UWA…

Simulink搭建一阶低通数字滤波器(设定X(n)为非0起始值)

一、一阶低通数字滤波器原理 一阶滤波&#xff0c;亦称一阶惯性滤波或一阶低通滤波。其数学表达式如下&#xff1a; 其中&#xff1a;α代表滤波系数&#xff1b;X(n)表示本次采样值&#xff1b;Y(n-1) 为上次滤波输出值&#xff1b;Y(n) 为本次滤波输出值。一阶低通滤波方法通…

让两个电脑通信的方法(TCP连接,UDP连接,C/S架构)

目录 TCP-面向连接UDP-面向无连接C/S架构服务器和客户端的工作过程C/S架构例子 让两个电脑通信的方法是 在C/S的基础上&#xff0c;采用TCP和UDP的方式连接 TCP-面向连接 UDP-面向无连接 C/S架构 服务器和客户端的工作过程 C/S架构例子 服务器与客户端通信的过程类似公司与客户…