Springboot 集成WebSocket作为客户端,含重连接功能,开箱即用
- 使用演示
public static void main(String[] args) throws Exception{//初始化socket客户端BaseWebSocketClient socketClient = BaseWebSocketClient.init("传入链接");//发送消息socketClient.sendMessage("填写需要发送的消息", (receive) -> {//这里编写接收消息的代码});}
只需要init后调用sendMessage方法即可,做到开箱即用。内部封装了失败重连接、断线重连接等功能。
基于Springboot工程
- 引入websocket依赖
<!--websocket--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>
- 开箱即用的工具类
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;import javax.websocket.ClientEndpoint;
import javax.websocket.CloseReason;
import javax.websocket.ContainerProvider;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;
import java.io.IOException;
import java.net.URI;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;/*** 封装简易websocket客户端的类,带重连机制*/
@ClientEndpoint
@Slf4j
public class BaseWebSocketClient {/*** 接收消息的函数,发送消息的时候传入*/private Consumer<String> receiveConsumer;/*** 连接socket的url,init的时候传入*/private String url;/*** 当前socket会话对象,init执行后生成*/private Session session;/*** 重连延迟2.5秒执行(连接需要时间,重连的时候延迟执行)*/private final Long reconnectTime = 2500L;/*** 重连次数*/private AtomicInteger retryReconnectCount = new AtomicInteger(0);/*** 发送消息重试次数*/private AtomicInteger reconnectSendCount = new AtomicInteger(0);/*** 发送消息最大重试次数*/private final int maxReconnectSendCount = 10;/*** 初始化,初始化完才能正常使用** @param url websocket连接的地址*/public static BaseWebSocketClient init(String url) throws Exception {BaseWebSocketClient client = new BaseWebSocketClient();URI uri = new URI(url);WebSocketContainer container = ContainerProvider.getWebSocketContainer();container.connectToServer(client, uri);client.setUrl(url);return client;}/*** 发送消息** @param message 消息* @param receiveConsumer 接收消息的函数*/public void sendMessage(String message, Consumer<String> receiveConsumer) {if (session == null) {throw new RuntimeException("socket还未初始化");}this.setReceiveConsumer(receiveConsumer);try {if (session.isOpen()) {//如果是open状态就能够发送消息session.getBasicRemote().sendText(message);reconnectSendCount = new AtomicInteger(0);} else {//进行重连this.reconnect();//重连2s后重新发送消息new Timer().schedule((new TimerTask() {@Overridepublic void run() {//为了防止重试次数过多,这里做一下限制,一直连接不成功的就不发消息了if (reconnectSendCount.getAndIncrement() >= maxReconnectSendCount) {return;}//再次重试发送消息sendMessage(message, receiveConsumer);}}), reconnectTime + reconnectTime);}} catch (Exception e) {log.error("socket发送消息失败,url:{}", url, e);}}/*** 手动关闭连接,当不使用的时候手动关闭,减少连接资源的损耗*/public void close() throws IOException {session.close(new CloseReason(CloseReason.CloseCodes.NORMAL_CLOSURE, "正常关闭"));}@OnOpenpublic void onOpen(Session session) {this.session = session;}/*** 接收消息,接收消息的响应动作由使用者在send的时候自行传入** @param message 消息内容*/@OnMessagepublic void onMessage(String message) {receiveConsumer.accept(unicodeDecode(message));}/*** 关闭时的操作,分为正常关闭和异常关闭,这里异常关闭的做重连操作*/@OnClosepublic void onClose(CloseReason closeStatus) throws Exception {if (closeStatus == null || closeStatus.getCloseCode() != CloseReason.CloseCodes.NORMAL_CLOSURE) {log.info("socket连接异常关闭url:{},closeStatus:{}", closeStatus, url);//重连reconnect();} else {log.info("socket连接关闭:{}", url);}}@OnErrorpublic void onError(Throwable throwable) throws Exception {log.error("socket连接异常,url:{}", url, throwable);//重连reconnect();}/*** 重连机制*/private void reconnect() throws Exception {if (session == null || session.isOpen()) {return;}//schedule里的this不是当前client对象Object that = this;new Timer().schedule(new TimerTask() {public void run() {//如果是打开的就不执行重连if (session.isOpen()) {return;}log.info("当前socket重连次数:{},url:{}", retryReconnectCount.getAndIncrement(), url);try {URI uri = new URI(url);WebSocketContainer container = ContainerProvider.getWebSocketContainer();container.connectToServer(that, uri);retryReconnectCount = new AtomicInteger(0);log.info("重连成功");} catch (Exception e) {log.error("socket重连失败,url:{}", url, e);}}}, reconnectTime);}private void setReceiveConsumer(Consumer<String> receiveConsumer) {this.receiveConsumer = receiveConsumer;}private void setUrl(String url) {this.url = url;}/*** unicode转中文*/public static String unicodeDecode(String string) {if (StringUtils.isBlank(string)) {return string;}Pattern pattern = Pattern.compile("(\\\\u(\\p{XDigit}{4}))");Matcher matcher = pattern.matcher(string);char ch;while (matcher.find()) {ch = (char) Integer.parseInt(matcher.group(2), 16);string = string.replace(matcher.group(1), String.valueOf(ch));}return string;}
}
相关文章:
![](https://www.ngui.cc/images/no-images.jpg)
Springboot 集成WebSocket作为客户端,含重连接功能,开箱即用
使用演示 public static void main(String[] args) throws Exception{//初始化socket客户端BaseWebSocketClient socketClient BaseWebSocketClient.init("传入链接");//发送消息socketClient.sendMessage("填写需要发送的消息", (receive) -> {//这里…...
![](https://www.ngui.cc/images/no-images.jpg)
java调整字符串
package 字符串练习;public class 调整字符串 {/* 如果调整成功则给提示,返回不成功也给提示调整 例如:abcde -> bcdea -> cdeab 就是把第一个值放到最后的位置上现在是给定两个字符串, 选定其中一个进行调整, (我们想一下,如果调整字符串的长度次,那不就是返回到原来的字…...
![](https://img-blog.csdnimg.cn/c33b6e2810f34a748b3cfef7a2a7c46d.png)
2023-9
内核向应用层发送netlink单播消息: nlmsg_unicast -> netlink_unicast -> netlink_sendskb -> __netlink_sendskb -> 把skb链入struct sock 的 sk_receive_queue 链表中,再调用sk->sk_data_ready(sk); -> sock_def_readable -> wak…...
![](https://img-blog.csdnimg.cn/85400546c8b44d8f9fbcfffc9d442bd8.jpg)
软考高级+系统架构设计师教程+第二版新版+电子版pdf
注意!!! 系统架构设计师出新版教程啦,2022年11月出版。所以今年下半年是新版第一次考试,不要再复习老版教程了,内容改动挺大的。 【内容简介】系统架构设计师教程(第2版)作为全国计…...
![](https://img-blog.csdnimg.cn/7bcc750e211541f9bf66388335c5ebeb.png)
【产品运营】如何提升B端产品竞争力(下)
“好产品不是能力内核,做好产品的流程才是” 一、建立需求池和需求反馈渠道 需求池管理是B端产品进化最重要的环节,它的重要性远超产品设计、开发等其他环节。 维护需求池有主动和被动两种。 主动维护是产品经理在参与售前、迭代、交付、售后、竞品分…...
![](https://www.ngui.cc/images/no-images.jpg)
uniapp 微信小程序使用echarts
本文目的:通过分包的方式,尽可能在微信小程序中使用最新的echarts。 当然你也可以直接使用现成的uchart或者市场里别人封好的echarts. 准备工作 下载echarts-for-weixin源码。 复制ec-canvas文件夹以及下属文件,在uniapp项目中与pages同级的地…...
![](https://img-blog.csdnimg.cn/4f1dd682c55047938e645231d3ef7698.png)
【漏洞复现】企望制造 ERP命令执行
漏洞描述 由于企望制造 ERP comboxstore.action接口权限设置不当,默认的配置可执行任意SQL语句,利用xp_cmdshell函数可远程执行命令,未经认证的攻击者可通过该漏洞获取服务器权限。 免责声明 技术文章仅供参考,任何个人和组织…...
![](https://img-blog.csdnimg.cn/3843c68ef1104afcbfe98c4cee2b6fc9.png#pic_center)
2023 “华为杯” 中国研究生数学建模竞赛(E题)深度剖析|数学建模完整代码+建模过程全解全析
问题一 血肿扩张风险相关因素探索建模 思路: 根据题目要求,首先需要判断每个患者是否发生了血肿扩张事件。根据定义,如果后续检查的血肿体积比首次检查增加≥6 mL或≥33%,则判断为发生了血肿扩张。 具体判断步骤: (1) 从表1中提取每个患者的入院首次影像检查…...
![](https://img-blog.csdnimg.cn/78b531f8496d4f4ebb4345bd1e35e903.png)
【腾讯云国际站】CDN内容分发网络特性介绍
为什么使用腾讯云国际站 CDN 内容分发网络? 当用户直接访问源站中的静态内容时,可能面临的体验问题: 客户离服务器越远,访问速度越慢。客户数量越多,网络带宽费用越高。跨境用户访问体验较差。 腾讯云国际站CDN 如何改…...
![](https://img-blog.csdnimg.cn/f35fff544c4447228d2cb858db1885d1.png#pic_center)
【工业机器人视觉】
工业机器人视觉 工业机器人的定位、抓取任务是工业生产线上一项重要的应用,一般通过预先示教的方式让机器人执行预定的指令动作。但是,一旦工件的状态发生改变时,机器人便无法完成工作任务。区别:就像人睁眼走直线和闭眼走直线。…...
![](https://www.ngui.cc/images/no-images.jpg)
跨域(浏览器)
跨域问题 是前端开发中常遇到的一个挑战。由于浏览器的同源策略限制,前端在发起异步请求时会受到限制,只能向相同源(域名、协议和端口号都相同)的服务器发送请求。当请求的目标服务器与当前页面的源不一致时,就会触发…...
![](https://www.ngui.cc/images/no-images.jpg)
Leetcode 2866. Beautiful Towers II
Leetcode 2866. Beautiful Towers II 1. 解题思路2. 代码实现 题目链接:2866. Beautiful Towers II 1. 解题思路 这一题其实思路上还是比较明显的,就是一个单调数组的问题,问题在于说如果具体去设计这个单调数组。 我们从题目出发&#x…...
![](https://img-blog.csdnimg.cn/f9149f3594234c2ba9683f1957e7f3d7.png#pic_center)
电脑C盘爆红怎么办?(小白篇)
文章目录 前言:1、清理临时和系统文件2、更改电脑默认软件安装位置3、微信、QQ文件存储路径放在其它盘4、卸载一些不常用的软件彩蛋 前言: C盘作为电脑的系统盘,如果出现爆满或者剩余空间很小整个C盘变红,这样会导致电脑系统运行…...
![](https://www.ngui.cc/images/no-images.jpg)
Office Xml 2003转XLSX
一、使用到的依赖包 1、xelem-3.1.jar 下载地址:管网下载地址 2、poi-3.17.jar 下载地址:https://mvnrepository.com/artifact/org.apache.poi/poi 二、实现方法 1、Xml2003公式转XLSX公式算法 (1)Xml2003函数格式 SUM(R[-1…...
![](https://www.ngui.cc/images/no-images.jpg)
skyWalking搭建(一)
title: “SkyWalking搭建(一)” createTime: 2021-07-27T14:34:2108:00 updateTime: 2021-07-27T14:34:2108:00 draft: false author: “name” tags: [“skywalking”] categories: [“java”] description: “测试的” 基于 docker 部署 skywalking 并实现 SpringBoot 全链路…...
![](https://www.ngui.cc/images/no-images.jpg)
Golang开发--sync.WaitGroup
sync.WaitGroup 是 Go 语言标准库中的一个并发原语,用于等待一组并发操作的完成。它提供了一种简单的方式来跟踪一组 goroutine 的执行状态,并在所有 goroutine 完成后恢复执行。 下面是关于 sync.WaitGroup 的实现细节的详细解释: 创建 Wa…...
![](https://www.ngui.cc/images/no-images.jpg)
Linux命令教程:使用cat命令查看和处理文件
文章目录 教程:使用cat命令在Linux中查看和处理文件1. 引言2. cat命令的基本概述3. 查看文件内容4. 创建文件5. 文件重定向和管道6. 格式化和编辑文件7. 实际应用示例7.1 使用cat命令浏览日志文件7.2 利用cat命令合并多个配置文件7.3 使用cat命令将文件内容发送到其…...
![](https://img-blog.csdnimg.cn/30d92c3181dd4731b957d43c8d2f9544.png)
Websocket集群解决方案以及实战(附图文源码)
最近在项目中在做一个消息推送的功能,比如客户下单之后通知给给对应的客户发送系统通知,这种消息推送需要使用到全双工的websocket推送消息。 所谓的全双工表示客户端和服务端都能向对方发送消息。不使用同样是全双工的http是因为http只能由客户端主动发…...
![](https://www.ngui.cc/images/no-images.jpg)
科技的成就(五十一)
397、初等数论的不可解问题 1936 年 4 月,邱奇证明判定性问题不可解。33 岁的邱奇发表论文《初等数论的不可解问题》,运用λ演算给出了判定性问题一个否定的答案。λ演算是一套从数学逻辑中发展起来的形式系统,采用变量绑定和替换,…...
![](https://img-blog.csdnimg.cn/3e8a40ea6c9c4ac6a116eec4946fe393.png)
Tomcat8 任意写文件PUT方法 (CVE-2017-12615)
Tomcat 任意写文件PUT方法 (CVE-2017-12615) 文章目录 Tomcat 任意写文件PUT方法 (CVE-2017-12615)1 在线漏洞解读:2 版本影响3 环境搭建4 漏洞复现4.1 访问4.2 POC攻击点4.2.1 直接发送以下数据包,然后shell将被写入Web根目录。4.2.2 访问是否通,可以访…...
![](https://www.ngui.cc/images/no-images.jpg)
SAP服务器修改主机名操作手册
1、业务背景 SAP服务器P2V:虚拟化后的服务器主机名(或叫计算机名、设备名,hostname,下文同)会和原参照克隆的服务器主机名一样,若两台服务器处于同一网域,会出现域冲突,导致以下事故发生 (1)、使得原服务器出现掉域情况(DEV->CLN->PRD后台服务器访问失效) …...
![](https://img-blog.csdnimg.cn/0a17f23e32cc42bd804b87148b3c075f.png#pic_center)
【大数据】Doris 构建实时数仓落地方案详解(一):实时数据仓库概述
本系列包含: Doris 构建实时数仓落地方案详解(一):实时数据仓库概述Doris 构建实时数仓落地方案详解(二):Doris 核心功能解读Doris 构建实时数仓落地方案详解(三)&#…...
![](https://img-blog.csdnimg.cn/1b853ed154cc4197bbc9a5cd441f83d0.png)
C++ list容器的实现及讲解
所需要的基础知识 对C类的基本了解 默认构造函数 操作符重载 this指针 引用 模板等知识具有一定的了解,阅读该文章会很轻松。 链表节点 template<class T>struct list_node{T _data;list_node<T>* _next;list_node<T>* _prev;list_node(const T&…...
![](https://img-blog.csdnimg.cn/ec5d1c22dc93493aa62e460987e051ae.png)
前端项目练习(练习-002-NodeJS项目初始化)
首先,创建一个web-002项目,内容和web-001一样。 下一步,规范一下项目结构,将html,js,css三个文件放到 src/view目录下面: 由于html引入css和js时,使用的是相对路径,所以…...
![](https://img-blog.csdnimg.cn/5ab92a30e02d484889e1a7743937dcc6.png)
C++QT day11
绘制时钟 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPaintEvent>//绘制事件类 #include <QDebug>//信息调试类 #include <QPainter>//画家类 #include <QTimer>//定时器类 #include <QTime> #include &…...
![](https://img-blog.csdnimg.cn/15f5202872d74787a88b502c92b46ed6.png)
Stable DIffusion 炫酷应用 | AI嵌入艺术字+光影光效
目录 1 生成AI艺术字基本流程 1.1 生成黑白图 1.2 启用ControlNet 参数设置 1.3 选择大模型 写提示词 2 不同效果组合 2.1 更改提示词 2.2 更改ControlNet 2.2.1 更改模型或者预处理器 2.2.2 更改参数 3. 其他应用 3.1 AI光影字 本节需要用到ControlNet,可…...
![](https://img-blog.csdnimg.cn/51baf48a44884f7eac75b3718fe50307.png)
C#通过重写Panel改变边框颜色与宽度的方法
在C#中,Panel控件是一个容器控件,用于在窗体或用户控件中创建一个可用于容纳其他控件的面板。Panel提供了一种将相关控件组合在一起并进行布局的方式。以下是Panel控件的详细使用方法: 在窗体上放置 Panel 控件: 在 Visual Studio 的窗体设计器中,从工具箱中拖动并放置一…...
![](https://img-blog.csdnimg.cn/fa372a73669a43e88b9e549a1c05ceae.png)
Vue2+ElementUI 静态首页案例
源码 <template><div class"app-container home"><el-row type"flex" justify"space-around" class"row-bg"><el-card class"box-card cardDiv1"><el-col :span"5"><div clas…...
![](https://img-blog.csdnimg.cn/a785b7240bce4cb68fdcfad22a2af115.png)
Linux的socket通信
关于套接字通信定义如下: 套接字对应程序猿来说就是一套网络通信的接口,使用这套接口就可以完成网络通信。网络通信的主体主要分为两部分:客户端和服务器端。在客户端和服务器通信的时候需要频繁提到三个概念:IP、端口、通信数据&…...
![](https://www.ngui.cc/images/no-images.jpg)
MySQL学习大纲
了解 MySQL 的基础知识和命令是使用此数据库的前提。以下是一些必须了解的 MySQL 概念和命令,包括基础的 CRUD(创建,读取,更新,删除)操作,以及一些高级功能: 1. 安装和启动 命令su…...
java做网站模版多站管理/有人看片吗免费观看视频
转载于:https://www.cnblogs.com/upzone/archive/2006/05/05/392235.html...
![](http://static.blog.csdn.net/images/save_snippets.png)
icp备案证书号查询/沈阳网站制作优化推广
Spring实现定时任务方法 标签: springquartztask 2017-03-11 02:02 190人阅读 评论(0) 收藏 举报 分类: spring(3) 作者同类文章Xtask quartz 版权声明:本文为博主原创文章࿰…...
![](/images/no-images.jpg)
wordpress站点迁移/广告关键词有哪些类型
随着平台的更换,现在市场上的主流内存已经由DDR顺利的过渡到了DDR2,而DDR3也将出现在INTEL今年下半年的蓝图上。面对越来越多的内存品牌,很多朋友都问我,什么牌子的内存比较好,哪几个品牌比较实惠?最近几天…...
![](/images/no-images.jpg)
类似于众人帮的做任务赚佣金网站/友情链接交换要注意哪些问题
要在 Java 中获取字符串的编码格式,您可以使用 Java 的 Charset 类。您可以通过以下方式获取字符串的编码: String str "your string"; Charset charset Charset.forName("UTF-8"); System.out.println(charset.displayName());其中…...
![](/images/no-images.jpg)
hot插件 wordpress/短视频拍摄剪辑培训班
前言 互联网可信身份认证平台签发微信身份证。12月25日广州市公安局南沙区分局、腾讯等10余家单位共发微警云联盟并广州南沙成立,现场联盟成员单位共签署合作框架协议并签发全国首张微信身份证网证(身份证网络版或电子版)。该网证由公安部第一…...
wordpress上卖什么用/网站seo优化案例
当前,我国融资租赁业正处于转型发展的关键时期。在推动经济高质量发展的浪潮之下,除了要充分发挥行业的跨界属性,延伸业务链。同时还要借助大数据等新兴技术,提升业务创新能力、风险防控能力。 关键词:融资租赁 机遇 …...