快速搭建springboot websocket客户端
一、前言
WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。
HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。
浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。
二、快速搭建springboot-websocket项目的服务端
1 导入依赖
<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></dependency>
2 创建配置类
@Configuration
public class WebSocketConfig {@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}
}
3 创建WebSocketServer服务类 用来接收数据
websocket的常用注解只有这5个
@ServerEndpoint注意上下文路径,websocket连接地址
@OnMessage只有第一次加载websocket的时候,会调用,生命周期只有一次
@OnClose只有关闭websocket链接的时候,会调用,生命周期只有一次
@OnMessage每次接收信息的时候,都会调用,调用比较频繁
@OnError发生错误的时候调调用
/*** 类似RequestMapping的地址* ws://localhost:8080/ws/000001*/
@ServerEndpoint("/ws/{uuid}")
@Component
public class WebSocketServer {private Session session; //客户端会话//存放每个客户端的连接会话public static ConcurrentHashMap<String,WebSocketServer> clients = new ConcurrentHashMap<>();//开启连接//存入连接回话中@OnOpenpublic void onOpen(Session session, @PathParam( "uuid") String uuid){System.out.println("当前的uuid为:"+uuid);this.session = session;clients.put(uuid,this);}//发送消息@OnMessagepublic void OnMessage(String msg, @PathParam( "uuid") String uuid){System.out.println("当前的uuid为:"+uuid);System.out.println("收到消息: "+msg);}//关闭连接@OnClosepublic void onClose(@PathParam( "uuid") String uuid){System.out.println("当前的uuid为:"+uuid);System.out.println("关闭socket连接"+uuid);clients.remove(uuid);}//发生异常的情况@OnErrorpublic void onError(Throwable error) {error.printStackTrace();}}
4 启动项目

三、一般都是前端为客户端,后端为服务端这种方式
前端客户端,我不会,需要的自己百度,哈哈哈
四、搭建java-websocket客户端
该案例,只是告诉大家,可以用java搭建客户端
4.1 依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.java-websocket</groupId><artifactId>Java-WebSocket</artifactId><version>1.3.5</version></dependency>
4.2 客户端代码
@Component
public class WebSocketConfig {@Beanpublic WebSocketClient webSocketClient() {try {WebSocketClient webSocketClient = new WebSocketClient(new URI("ws://localhost:8081/ws/000001"),new Draft_6455()) {@Overridepublic void onOpen(ServerHandshake handshakedata) {System.out.println("ws 连接成功");}@Overridepublic void onMessage(String message) {System.out.println("ws 收到消息"+message);}@Overridepublic void onClose(int code, String reason, boolean remote) {System.out.println("ws 退出");}@Overridepublic void onError(Exception ex) {System.out.println("连接错误"+ex.getMessage());}};webSocketClient.connect();return webSocketClient;} catch (Exception e) {e.printStackTrace();}return null;}}
4.3 发送消息的代码
@SpringBootApplication
@RestController
public class SpringbootWebsocketClientApplication {@Autowiredprivate WebSocketClient webSocketClient;public static void main(String[] args) {SpringApplication.run(SpringbootWebsocketClientApplication.class, args);}@RequestMapping("/get")public String send(){webSocketClient.send("我是ws客户端,你好!!!");return "发送成功";}}
4.4 结果

4.5 服务端收到消息
当前的uuid为:000001
收到消息: 我是ws客户端,你好!!!
五、websocket传递头信息,协议头token的前后端解决方案
js websocket 传递token
websocket协议在握手阶段借用了HTTP的协议,但是在JavaScript websocketAPI中并没有修改请求头的方法。
1.1 基于协议头
websocket请求头中可以包含Sec-WebSocket-Protocol这个属性,该属性是一个自定义的子协议。它从客户端发送到服务器并返回从服务器到客户端确认子协议。我们可以利用这个属性添加token。
var token='fasdfadfasdfa'var ws = new WebSocket("ws://" + url+ "/webSocketServer",[token]);
后台取出websocket协议头的参数
2.1 取出token
token = ((HttpServletRequest) servletRequest).getHeader("Sec-WebSocket-Protocol");2.2 注意大坑
如果传递了token参数,后端响应的时候,也必须带上这个token响应!否则前端接收不到数据!
可以采用servlet的过滤器来做
@Order(1)
@Component
@WebFilter(filterName = "WebsocketFilter", urlPatterns = "/home/*")
public class WebsocketFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletResponse response = (HttpServletResponse) servletResponse;String token = ((HttpServletRequest) servletRequest).getHeader("Sec-WebSocket-Protocol");response.setHeader("Sec-WebSocket-Protocol",token);filterChain.doFilter(servletRequest, servletResponse);}@Overridepublic void destroy() {}
}
六、结尾
websocket最伟大之处在于服务器和客户端可以在给定的时间范围内的任意时刻,相互推送信息。 浏览器和服务器只需要要做一个握手的动作,在建立连接之后,服务器可以主动传送数据给客户端,客户端也可以随时向服务器发送数据。第一、WebSocket是HTML5中的协议,支持持久连接;而Http协议不支持持久连接。第二、首先,Websocket是一个持久化的协议,相对于HTTP这种非持久的协议来说HTTP的生命周期通过 Request 来界定,也就是一个 Request 一个 Response ,那么在 HTTP1.0 中,这次HTTP请求就结束了。在HTTP1.1中进行了改进,使得有一个keep-alive,也就是说,在一个HTTP连接中,可以发送多个Request,接收多个Response。但是请记住 Request = Response , 在HTTP中永远是这样,也就是说一个request只能有一个response。而且这个response也是被动的,不能主动发起。第三、传统的http请求,其并发能力都是依赖同时发起多个TCP连接访问服务器实现的(因此并发数受限于浏览器允许的并发连接数),而websocket则允许我们在一条ws连接上同时并发多个请求,即在A请求发出后A响应还未到达,就可以继续发出B请求。由于TCP的慢启动特性(新连接速度上来是需要时间的),以及连接本身的握手损耗,都使得websocket协议的这一特性有很大的效率提升。第四、http协议的头部太大,且每个请求携带的几百上千字节的头部大部分是重复的,很多时候可能响应都远没有请求中的header空间大。如此多无效的内容传递是因为无法利用上一条请求内容,websocket则因为复用长连接而没有这一问题。第五、当需要实现客户端刷新消息时,传统方案往往通过定时ajax请求实现,实际上对多数用户多数时间下这些请求都是无意义了,并且非常占用资源,websocket资源占用就小很多
相关文章:
快速搭建springboot websocket客户端
一、前言WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽&…...
Python 操作 MongoDB 详解
嗨害大家好鸭!我是芝士❤ 一、前言 MongoDB属于 NoSQL(非关系型数据库), 是一个基于分布式文件存储的开源数据库系统。 二、操作 MongoDB 1. 安装 pymongo python 使用第三方库来连接操作 MongoDB, 所以我们首先安…...
虹科案例 | 丝芙兰xDomo:全球美妆巨头商业智能新玩法
全球美妆行业的佼佼者丝芙兰,其走向成功绝非仅依靠品牌知名度和营销手段。身为数据驱动型企业,2018年以来,丝芙兰就率先在行业内采用虹科提供的Domo商业智能进行数据分析和决策,并首先享受了运营优化、效率提升所带来的商业价值。…...
10种优雅的MyBatis写法,同事用了都说好
用来循环容器的标签forEach,查看例子 foreach元素的属性主要有item,index,collection,open,separator,close。 item:集合中元素迭代时的别名, index:集合中元素迭代时的索引 open…...
SQL删除记录方式汇总
大家好,我是RecordLiu! 今天给大家分享的是SQL中删除记录的不同方式,我会用几道真题来给大家讲解。 题目直达链接: 牛客网在线SQL编程练习 切换到SQL篇就能看到了。 我这里先列下知识点: SQL中进行简单删除的语法是什么?SQL…...
用in函数嵌入子查询作为条件时查出结果为空
用in函数嵌入子查询作为条件时查出结果为空 问题: SELECT * FROM SGGCDB_VIEW sv WHERE RES_ID IN (SELECT urrv.RES_ID FROM IBPS_ERP.USER_ROLE_RES_VIEW urrv WHERE urrv.ID_ 1069978138403930112 )结果未空值。 原因: 首先,SELECT u…...
电商行业如何利用飞项解决跨部门协作难题
在电商行业中,跨部门合作是最常见的事。从产品方案到设计方案,从市场定价到销售策略,从采购需求到成本清单……在电商新品研发到正式售卖的过程中,存在着大量跨部门协作与逆向流程,但任务零碎、沟通难、进度难同步、文…...
全网最详细,Jmeter性能测试-性能基础详解,参数化函数取值(二)
目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 参数化详解 Jmeter中…...
选择排序的简单理解
详细描述 选择排序的工作原理是:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾…...
使用js封装一个循环链表
直接不说废话,直接上代码,这里继承了单向链表的类LinkList ,可以查看之前的文章,点这里 class Node {constructor(element) {this.element element;this.next null;} }class CirularLinkedList extends LinkList {constructor(…...
NumPy 秘籍中文第二版:二、高级索引和数组概念
原文:NumPy Cookbook - Second Edition 协议:CC BY-NC-SA 4.0 译者:飞龙 在本章中,我们将介绍以下秘籍: 安装 SciPy安装 PIL调整图像大小比较视图和副本翻转 Lena花式索引位置列表索引布尔值索引数独的步幅技巧广播数…...
新品-图灵超频工作站GT430M介绍
曾经历史 UltraLAB GTxxxM系列是西安坤隆公司专注于超频高速计算应用的图形工作站。 2008年 获取排名第一、二的中国象棋软件均采用该机型。 2019年 推出采用Intel 超频Xeon(28核4.8GHz)显著提升电磁仿真频域算法求解、第一个解决8K视频解码与渲染。 今…...
js时间格式化精确到毫秒
/*** 数字前置补零* param value 值* param length 位数* returns {string}*/ export function digit(value, length 2) {if (typeof value "undefined" ||value null ||String(value).length > length) {return value;}return (Array(length).join("0&qu…...
QT样式表详解
本文详细介绍qt的样式表,包含样式表如何使用,常见语句和选择器。 背景说明 样式表用于设置外观,他是设置控件外观的方式之一。其他方式如下: 控件的成员函数,如QWidget::setBackground样式表调色板 优先级依次提高…...
最值得入手的好物有哪些,推荐几款实用的数码好物
随着科技的进步,越来越多的数码产品不断的出现在我们的生活中,这其中也不乏一些实用的数码产品,让我们可以享受更舒适的生活,提高我们的工作效率。下面就给大家分享几款我最近使用过的一些数码产品,它们不仅功能强大而…...
【20230407】NVIDIA显卡算力、Jetson比较
1 基本概念 1.1 算力单位 TOPS:指的是每秒钟可以执行的整数运算次数,它代表着计算机在处理图像、音频等任务时的处理能力。TOPS的单位是万亿次每秒(trillion operations per second)。一般是指整数运算能力INT8。 TFLOPS&#…...
dsl语法
查询 1.查询所有(默认有分页查询) #查询所有 GET /hotel/_search {"query": {"match_all": {}} } 2.match查询(条件查询)-----包含四川和外滩的信息,信息匹配度越高越靠前,两者存在一…...
不让CPU偷懒
文章资料摘自——《程序员的自我修养》 为了防止cpu执行完该程序后需要等待程序员手动加入下一个程序,才可以继续运行,这里大大浪费了cpu的效率,要知道cpu是十分昂贵的。 多道程序 在计算机发展的早期,CPU使用十分不方便&#x…...
动力节点王鹤SpringBoot3笔记——第七章 视图技术Thymeleaf
目录 第七章 视图技术Thymeleaf 前言 7.1 表达式 7.2 if-for 第七章 视图技术Thymeleaf 前言 Thymeleaf 是一个表现层的模板引擎, 一般被使用在 Web 环境中,它可以处理 HTML, XML、 JS 等文档,简单来说,它可以将 JSP 作…...
从比特保存和信息保存看数字资源长期保存
引用IBM以色列海法实验室的观点,数字资源长期保存包含两个层面含义,即比特保存与信息保存。也就是说,要实现数字资源的长期保存,必须同时做到比特保存和信息保存。 一 概念 01 比特保存,也叫物理保存,主…...
基于STM32与ADS1258的高精度电流数据采集方案实现
1. 高精度电流采集系统设计思路 电流测量在工业自动化、新能源和车载电子等领域都是基础但关键的环节。传统方案使用普通ADC配合分压电阻,精度往往只能达到1%左右,而采用ADS1258这类24位Σ-Δ ADC,配合STM32主控,可以实现0.01%级的…...
GHelper开源工具深度评测:如何为华硕笔记本实现轻量化硬件控制
GHelper开源工具深度评测:如何为华硕笔记本实现轻量化硬件控制 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops. Control tool for ROG Zephyrus G14, G15, G16, M16, Flow X13, Flow X16, TUF, Strix, Scar and other models …...
前端面试高频考点总结(不仅有考点,还有对应解答)
2026年 AI面试 经验分享 前端面试核心要点 技术考察转向实际场景与新兴技术,重点包括: JavaScript/TypeScript核心机制与编码能力React/Vue3的高阶特性与原理工程化与性能优化体系网络/安全与综合性场景题 3-5年经验者需突出: 技术原理深度&a…...
Windows 7如何突破Python版本限制?企业级兼容性解决方案指南
Windows 7如何突破Python版本限制?企业级兼容性解决方案指南 【免费下载链接】PythonVista Python 3.9 installers that support Windows 7 SP1 and Windows Server 2008 R2 项目地址: https://gitcode.com/gh_mirrors/py/PythonVista 一、痛点分析ÿ…...
华为交换机Eth-Trunk配置实战:手工与LACP模式全解析(附排错指南)
华为交换机Eth-Trunk深度配置指南:从手工模式到LACP模式的技术实践 在企业网络架构中,带宽瓶颈和单点故障一直是困扰网络工程师的两大难题。记得去年参与某金融数据中心改造时,核心交换机之间的千兆链路在业务高峰时段频繁出现拥塞告警&#…...
飞机表面缺陷识别分割数据集labelme格式4612张5类别
注意数据集中有超过一半图片是增强图片数据集格式:labelme格式(不包含mask文件,仅仅包含jpg图片和对应的json文件)图片数量(jpg文件个数):4612标注数量(json文件个数):4612标注类别数:5标注类别名称:["Crack"…...
论文写作“黑科技”:书匠策AI,让课程论文创作如虎添翼!
在学术探索的征途中,每一位学子都渴望拥有一把开启智慧之门的钥匙,尤其是在面对课程论文这一挑战时,更是希望能有得力助手助自己一臂之力。今天,就让我带你揭开书匠策AI科研工具的神秘面纱,看看它是如何成为你课程论文…...
如何用pose-search在5分钟内构建智能人体姿态分析系统
如何用pose-search在5分钟内构建智能人体姿态分析系统 【免费下载链接】pose-search x6ud.github.io/pose-search 项目地址: https://gitcode.com/gh_mirrors/po/pose-search 你是否曾经想过为你的应用添加实时人体姿态识别功能,但又担心技术门槛太高&#x…...
个人隐私守护者:Qwen-Image-Edit本地化部署,修图数据不出本地
个人隐私守护者:Qwen-Image-Edit本地化部署,修图数据不出本地 想要体验AI修图的魔力,又担心隐私泄露?Qwen-Image-Edit本地化部署方案让你鱼与熊掌兼得。本文将带你从零开始,在本地服务器上部署这款强大的图像编辑工具…...
保姆级教程:用Brainstorm搞定运动想象EEG分析,从时频图到分类器实战
保姆级教程:用Brainstorm搞定运动想象EEG分析,从时频图到分类器实战 运动想象脑电(EEG)分析是脑机接口(BCI)研究中的经典课题,也是许多研究生和初学者的第一个实战项目。但面对复杂的信号处理和…...
