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

53、springboot对websocket的支持有两种方式-------1、基于注解开发 WebSocket ,简洁实现多人聊天界面

基于注解开发 WebSocket

–注解就是: @OnOpen、 @OnClose 、 @OnMessage 、@OnError这些

★ WebSocket的两种开发方式

▲ Spring Boot为WebSocket提供了两种开发方式:

  • 基于spring-boot-starter-websocket.jar开发WebSocket

  • 基于Spring WebFlux开发WebSocket

两种方式对比:
springboot API
在这里插入图片描述

Socket:套接字。
插座。
在通信的两端分别建立虚拟的Socket(插座),网络协议就会负责在两个Socket之间建立虚拟线路。然后通信的两端即可通过该虚拟线路进行实时的、可靠的通信。

WebSocket 就是在服务器与客户端浏览器之间的建立双向通信的Socket。从而保证服务器与客户端浏览器之间可进行实时的双向通信。

▲ 传统Web应用: 请求 - 响应。 这种模型没办法让服务器主动将数据推送客户端的浏览器。 还有比如SSE(服务器事件机制)

★ 基于Spring Boot自动配置来开发WebSocket

两步:

(1)定义一个WebSocket处理类

该处理类有两种开发方式(历史原因造成):第一种方式:   - 直接使用JDK提供的 WebSocket注解 修饰处理方法,并使用 @ServerEndpoint  注解修饰该处理类即可。WebSocket注解就是: @OnOpen、 @OnClose 、 @OnMessage 、@OnError这些——这种方式下方法签名可以随便写,方法参数也可以自行定义,非常灵活。官方也推荐尽量使用第一种方式第二种方式:    - 实现WebSocketHandler接口、并实现该接口中定义的各种处理方法。——Java语法规定,实现接口时,实现的方法必须与接口中定义的方法有相同的方法签名。——这种方式就不够灵活。

(2)配置或导出WebSocket处理类

如果采用注解方式开发WebSocket处理类,
这一步只需要在 Spring容器 中配置一个ServerEndpointExporter Bean  (导出器)即可。
该导出器会负责将容器中所有的@ServerEndpoint注解修饰的处理Bean都导出成WebSocket。
因此无论程序有多少个WebSocket处理Bean,导出器Bean只要配置一个即可。
——非常简单、方便。如果采用是实现接口的方式开发WebSocket处理类,
这一步就需要使用WebSocketConfigurer来配置WebSocket。

代码演示

创建项目
在这里插入图片描述

开发websocket的两步。
在这里插入图片描述

注解:@PathParam()

属于 WebSocket 的,用于获取路径上的参数。
在这里插入图片描述

发送消息的简单解释:
在这里插入图片描述

完整代码:

前端页面
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title> 基于WebSocket的多人聊天 </title><script type="text/javascript">// 定义Web Socket对象var webSocket = null;let sendMsg = function(){if (webSocket == null || webSocket.readyState != 1){document.getElementById('show').innerHTML+= "还未连接服务器,请先连接WebSocket服务器<br>";return;}let inputElement = document.getElementById('msg');// 发送消息webSocket.send(inputElement.value);// 清空单行文本框inputElement.value = "";}let connect = function(){let name = document.getElementById('name').value.trim();if (name == null || name == ""){document.getElementById('show').innerHTML+= "用户名不能为空<br>";return;}if (webSocket && webSocket.readyState == 1){webSocket.close();}webSocket = new WebSocket("ws://127.0.0.1:8080/websocket/" + name);webSocket.onopen = function(){document.getElementById('show').innerHTML+= "恭喜您,连接服务器成功!<br>";document.getElementById('name').value = "";// 为onmessage事件绑定监听器,接收消息webSocket.onmessage= function(event){// 接收、并显示消息document.getElementById('show').innerHTML+= event.data + "<br>";}};}</script>
</head>
<body>
<input type="text" size="20" id="name" name="name"/>
<input type="button" value="连接" onclick="connect();"/>
<div style="width:600px;height:240px;overflow-y:auto;border:1px solid #333;" id="show"></div>
<input type="text" size="80" id="msg" name="msg"/>
<input type="button" value="发送" onclick="sendMsg();"/>
</body>
</html>
MyWebSocketHandler 注解开发各方法
package cn.ljh.app.websocket;import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;//基于注解开发 WebSocket --注解就是: @OnOpen、 @OnClose 、 @OnMessage 、@OnError这些@Component
//这个注解需要指定指定映射地址
@ServerEndpoint("/websocket/{name}")
@Slf4j
public class MyWebSocketHandler
{//可以用注解来修饰不同的处理方法//假设是一个聊天室,map 中的key 是每个用户的 Session , value 是用户的name//创建一个线程安全的map ,用这个map来保存各用户的Session与name之间的对应关系public final static Map<Session,String> myClients = new ConcurrentHashMap<>();//当浏览器 与 Websocket 服务器建立连接的时候触发该方法//这个Session参数代表浏览器 与 WebSocket 服务器所建立连接会话,它用于通信。//这个 @PathParam() 相当于spring mvc 中的 @PathVariable,//都是用来获取路径中的参数--获取这个路径"/websocket/{name}" 中的name参数@OnOpenpublic void onOpen(Session session , @PathParam("name") String name){//当用户登录的时候,把信息存进去myClients.put(session,name);log.debug("--------- onOpen ----------");}//当浏览器与WebSocket服务器 关闭的时候触发该方法@OnClosepublic void onClose(Session session){//当连接关闭的时候,就将该客户端从map中删除myClients.remove(session);log.debug("--------- onClose ----------");}//当 WebSocket服务器 收到 浏览器 发送过来的消息时触发该方法@SneakyThrows@OnMessagepublic String onMessage(Session session, String message){//收到消息,把消息广播给每个客户端      keySet()-->将map中的所有key存到set集合中for (Session client : myClients.keySet()){//此处的 client 就代表每个客户端//向client 发送信息,这个 client 代表了一个浏览器//getBasicRemote() 表示给客户端发送消息是同步的、阻塞的    ,   sendText()  发送消息client.getBasicRemote().sendText(myClients.get(session)+" 说:"+message);}log.debug("--------- onMessage ----------"+message);return null;}//但 WebSocket 服务器 与 浏览器通信出现异常时触发该方法//这个 Throwable 参数就代表了出现的异常@OnErrorpublic void onError(Session session, Throwable ex){//当连接出现异常的时候,将该客户端从 Map 中栅除myClients.remove(session);log.debug("--------- onError ----------");}}
MyWebSocketConfig 配置 WebSocket 导出器
package cn.ljh.app.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;/*** author JH* date 2023/9/7  0007 12:28*/@Configuration
public class MyWebSocketConfig
{/**配置 WebSocket 导出器**   该导出器会负责将容器中所有的 @ServerEndpoint 注解修饰的 处理Bean 都导出成 WebSocket。*  因此无论程序有多少个 WebSocket 处理Bean,导出器Bean 只要配置一个即可。*/@Beanpublic ServerEndpointExporter serverEndpointExporter(){return new ServerEndpointExporter();}
}
application.yml 配置日志级别
#给这个包设置日志级别为debug
logging:level:cn:ljh:app:websocket: debug

测试:

进行websocket连接
在这里插入图片描述

成功基于注解开发WebSocket 的多人聊天室
在这里插入图片描述

相关文章:

53、springboot对websocket的支持有两种方式-------1、基于注解开发 WebSocket ,简洁实现多人聊天界面

基于注解开发 WebSocket –注解就是&#xff1a; OnOpen、 OnClose 、 OnMessage 、OnError这些 ★ WebSocket的两种开发方式 ▲ Spring Boot为WebSocket提供了两种开发方式&#xff1a; 基于spring-boot-starter-websocket.jar开发WebSocket 基于Spring WebFlux开发WebSoc…...

18 Linux之Python定制篇-Python开发平台Ubuntu

18 Linux之Python定制篇-Python开发平台Ubuntu 文章目录 18 Linux之Python定制篇-Python开发平台Ubuntu18.1 安装Ubuntu虚拟机18.4 Ubuntu的root用户18.5 Ubuntu下开发Python 学习视频来自于B站【小白入门 通俗易懂】2021韩顺平 一周学会Linux。可能会用到的资料有如下所示&…...

AMEYA360:士兰微推出600A/1200V IGBT汽车驱动模块,提升充电速度与行驶动力

随着人们对环保意识的提高和汽车驾驶体验感的不断追求&#xff0c;新能源汽车的市场需求逐渐增大&#xff0c;已然成为汽车发展的大趋势&#xff0c;但是新能源汽车充电时间长、续航里程短等问题仍然是汽车厂商和车主们的痛点。因此&#xff0c;需要更好的汽车驱动产品来实现“…...

【Linux】Epoll Reactor【反应堆】模式的工作流程

Reactor模式的工作流程 主线程往epoll内核事件表中注册socket上的就绪事件。主线程调用epoll_wait等待socket上有数据可读。当socket上有数据可读时&#xff0c;epoll_wait通知主线程。主线程将socket可读事件放入请求队列。睡眠在请求队列上的某个工作线程被唤醒&#xff0c;…...

Php“梦寻”淘宝天猫商品详情数据接口,淘宝商品详情数据API接口,淘宝API接口申请指南(含代码示例)

淘宝商品详情接口 API 是开放平台提供的一种 API 接口&#xff0c;它可以帮助开发者获取淘宝商品的详细信息&#xff0c;包括商品的标题、描述、图片等信息。在淘宝电商平台的开发中&#xff0c;淘宝详情接口 API 是非常常用的 API&#xff0c;因此本文将详细介绍淘宝详情接口 …...

驱动轴相机参数设置Web前端界面开发

一、基于Django的Web应用界面的开发&#xff1a; 在Realtimeresults.html上添加一个按钮组件&#xff0c;获取检测到的轴型和车轮信息&#xff0c;点击后可以获取package.json里存放的json数据&#xff0c;效果如下&#xff1a; 实现逻辑&#xff1a;需要从URL设置、视图函数、…...

论文简读 LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS

论文地址&#xff1a;https://arxiv.org/pdf/2106.09685.pdf 项目地址&#xff1a;https://github.com/microsoft/LoRA 全文翻译地址&#xff1a;https://zhuanlan.zhihu.com/p/611557340 本来想自行翻译的&#xff0c;但最近没有空 1、关键凝练 1.1 LORA是什么&#xff1f; …...

23062网络编程day7

网络聊天室编写&#xff08;基于UDP&#xff09; 服务器 #include <myhead.h>#define PORT 8888 //端口号&#xff1a;接收方绑定的端口号 #define IP "192.168.114.56" //本机IP#define ERR_MSG(msg) do{\fprintf(stderr, "__%d__:&…...

Java面向对象学习笔记-2

前言 本文介绍了Java中类的定义和对象的创建的基本概念。我们通过示例代码演示了如何定义不同类型的类&#xff0c;包括管理员信息、顾客信息、学校信息和访客信息&#xff0c;并展示了如何创建这些类的对象以及如何访问它们的属性和方法。这些示例有助于理解面向对象编程的基…...

入栏需看——学习记忆

记忆方法千千种&#xff0c;本栏意在梳理其中道道来&#xff0c;旦有小得&#xff0c;肥肠幸耶。从不同角度分析学习记忆。 逻辑篇 有逻辑 用思维导图 思维导图记忆有逻辑的文本/内容 理论 巧记书本结构–思维导图 模仿 HCIE-Cloud Computing LAB备考第一步&#xff1a…...

[C++]杨辉三角

目录 题目 解题思路 代码实现 获取数字 打印函数 主函数 全部代码 运行结果 题目 给定一个非负整数numRows &#xff0c;生成「杨辉三角」的前numRows行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 解题思路 第k列的第i个数字的值第k-1列的(…...

算法通关村十三关-白银:数字与数学高频问题

有很多解题技巧&#xff0c;需要持续积累 1.数组实现加法专题 如果让你用数组来表示一个数&#xff0c;如何实现加法呢&#xff1f; 理论上仍然从数组末尾向前挨着计算就行了&#xff0c;但是实现的时候会发现很多问题&#xff0c;例如需要进位该怎么办&#xff1f; 进一步拓…...

【Linux】线程安全-互斥同步

文章目录 线程安全问题的引入线程互斥互斥概念互斥锁互斥锁的计数器当中如何保证原子性互斥锁基础API初始化互斥锁变量函数动态初始化静态初始化 加锁函数阻塞加锁非阻塞加锁带有超时时间的加锁 解锁函数销毁互斥锁函数 线程同步线程同步的必要性条件变量条件变量的使用原理条件…...

1.初识爬虫

爬虫是批量模拟网络请求的程序&#xff0c;想百度谷歌这种搜索类网站本质上就是爬虫 使用爬虫的时候不应该对别人的网站有严重的影响&#xff0c;比如你爬的频率太高了&#xff0c;让人家的网站崩溃了。不应该爬取网页上显示不到的内容&#xff0c;比如有一个直播的网站&#…...

TLA+学习记录1——hello world

0x01 TLA是个好工具 编程人员一个好习惯是凡事都想偷懒&#xff0c;当然是指要科学地偷懒&#xff0c;而不是真的偷懒。一直想找到一种能检验写出的代码&#xff0c;做出的设计是否真的完全正确&#xff0c;而不是靠经验检视、代码Review、反复测试去检验。因为上述方法不管怎…...

基于QWebEngine实现无头浏览器

无头浏览器 无头浏览器&#xff08;Headless Browser&#xff09;是一种没有图形用户界面&#xff08;GUI&#xff09;的浏览器。它通过在内存中渲染页面&#xff0c;然后将结果发送回请求它的用户或程序来实现对网页的访问&#xff0c;而不会在屏幕上显示网页。这种方式使得无…...

编译Micropython固件For树莓派Raspberry Pi Pico

1. 前言 由于想把自己编写的py文件打包的固件中&#xff0c;所以记录下如何编译micropython固件和打包。 2. 编译 最简单的方式就是在你的树莓派上进行&#xff0c;我用的是RP Pi2 下载所需文件&#xff1a; $ cd ~/ $ mkdir pico $ cd pico $ git clone -b pico https://gi…...

基于googlenet网络的动物种类识别算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ................................................................. % 获取输入层的尺寸 Inp…...

如何用Jmeter编写脚本压测?

随着商业业务不断扩张&#xff0c;调用adsearch服务频率越来越高&#xff0c;所以这次想做个压测&#xff0c;了解目前多少并发量可以到达adsearch服务的界值。 这次选用的jmeter压测工具&#xff0c;压测思路如图&#xff1a; 一、日志入参 日志选取的adsearch 的 getads部分…...

SpingMVC之拦截器使用详解

拦截器概述 SpringMVC的处理器拦截器,类似于Servlet开发中的过滤器Filter&#xff0c;用于对处理器进行预处理和后处理。 过滤器和拦截器区别 过滤器&#xff1a;依赖于servlet容器。在实现上基于函数回调&#xff0c;可以对几乎所有请求进行过滤&#xff0c;但是缺点是一个过…...

3秒守护隐私:Boss-Key重新定义窗口智能管理

3秒守护隐私&#xff1a;Boss-Key重新定义窗口智能管理 【免费下载链接】Boss-Key 老板来了&#xff1f;快用Boss-Key老板键一键隐藏静音当前窗口&#xff01;上班摸鱼必备神器 项目地址: https://gitcode.com/gh_mirrors/bo/Boss-Key 在数字化办公环境中&#xff0c;窗…...

独立开发者福音:Pixel Fashion Atelier镜像免配置+预设Prompt快速上手指南

独立开发者福音&#xff1a;Pixel Fashion Atelier镜像免配置预设Prompt快速上手指南 1. 为什么选择Pixel Fashion Atelier 如果你是一位独立游戏开发者或像素艺术爱好者&#xff0c;一定遇到过这样的困扰&#xff1a;想要快速生成高质量的像素风格时装素材&#xff0c;却苦于…...

3步解锁VR视频自由:让3D内容在任何设备重生

3步解锁VR视频自由&#xff1a;让3D内容在任何设备重生 【免费下载链接】VR-reversal VR-Reversal - Player for conversion of 3D video to 2D with optional saving of head tracking data and rendering out of 2D copies. 项目地址: https://gitcode.com/gh_mirrors/vr/V…...

Python实战:3种高效连接ClickHouse的方法对比(附性能测试)

Python实战&#xff1a;3种高效连接ClickHouse的方法对比&#xff08;附性能测试&#xff09; 在数据分析领域&#xff0c;ClickHouse凭借其卓越的列式存储和向量化执行引擎&#xff0c;已成为处理海量数据的首选解决方案之一。而Python作为数据科学家的瑞士军刀&#xff0c;如…...

PDF-Parser-1.0智能办公:告别手动复制粘贴的PDF处理方案

PDF-Parser-1.0智能办公&#xff1a;告别手动复制粘贴的PDF处理方案 1. 为什么需要智能PDF解析工具 在日常办公场景中&#xff0c;PDF文档处理是一个高频且痛苦的工作环节。根据统计&#xff0c;职场人士平均每周需要处理15-20份PDF文件&#xff0c;包括合同、报告、发票等各…...

如何为SortableJS实现高效自动化测试:拖拽功能的完整测试指南

如何为SortableJS实现高效自动化测试&#xff1a;拖拽功能的完整测试指南 【免费下载链接】Sortable Reorderable drag-and-drop lists for modern browsers and touch devices. No jQuery or framework required. 项目地址: https://gitcode.com/gh_mirrors/so/Sortable …...

QEMU监视器隐藏玩法:用TCP端口转发实现远程调试(2024最新版)

QEMU监视器隐藏玩法&#xff1a;用TCP端口转发实现远程调试&#xff08;2024最新版&#xff09; 在边缘计算和物联网设备调试中&#xff0c;经常需要跨越物理距离管理虚拟机。传统方式要求开发者必须物理接触设备或依赖图形界面&#xff0c;这在分布式场景中显得笨拙且低效。实…...

如何在macOS上制作Windows启动盘:WinDiskWriter终极指南

如何在macOS上制作Windows启动盘&#xff1a;WinDiskWriter终极指南 【免费下载链接】windiskwriter &#x1f5a5; A macOS app that creates bootable USB drives for Windows. &#x1f6e0; Patches Windows 11 to bypass TPM and Secure Boot requirements. 项目地址: h…...

CAN总线波特率计算器工具开发指南(Python+PyQt5)

CAN总线波特率计算器工具开发指南&#xff08;PythonPyQt5&#xff09; 在汽车电子工程领域&#xff0c;CAN总线作为车载网络的骨干&#xff0c;其通信质量直接影响整车系统的稳定性。而波特率作为CAN通信的基础参数&#xff0c;其配置精度直接决定了总线能否正常工作。传统的手…...

告别代码噩梦:用Awesome-Dify-Workflow零代码30分钟实现企业级登录系统

告别代码噩梦&#xff1a;用Awesome-Dify-Workflow零代码30分钟实现企业级登录系统 【免费下载链接】Awesome-Dify-Workflow 分享一些好用的 Dify DSL 工作流程&#xff0c;自用、学习两相宜。 Sharing some Dify workflows. 项目地址: https://gitcode.com/GitHub_Trending/…...