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;}
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

牛客java训练题 day1

9.24 day1 Q 1. this 指针是用来干什么的&#xff1f; 2.基类和派生类分别是指什么&#xff1f; 3.为什么方法中不能写静态变量 4. 解释一下ASCII码和ANSI码和两者的区别 5.简述j ava.io java.sql java.awt java.rmi 分别是什么类型的包 6. 看下面一段代码&#xff1a;…

Ubuntu安装RabbitMQ server - 在外远程访问

文章目录 前言1.安装erlang 语言2.安装rabbitMQ3. 内网穿透3.1 安装cpolar内网穿透(支持一键自动安装脚本)3.2 创建HTTP隧道 4. 公网远程连接5.固定公网TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址 前言 RabbitMQ是一个在 AMQP(高级消息队列协议)基…

安装OpenSearch

title: “安装opensearch” createTime: 2021-11-30T19:13:4508:00 updateTime: 2021-11-30T19:13:4508:00 draft: false author: “name” tags: [“es”,“安装”] categories: [“OpenSearch”] description: “测试的” 说明 基于Elasticsearch7.10.2 的 opensearch-1.1.…

使用QLoRA对Llama 2进行微调的详细笔记

使用QLoRA对Llama 2进行微调是我们常用的一个方法&#xff0c;但是在微调时会遇到各种各样的问题&#xff0c;所以在本文中&#xff0c;将尝试以详细注释的方式给出一些常见问题的答案。这些问题是特定于代码的&#xff0c;大多数注释都是针对所涉及的开源库以及所使用的方法和…

高并发系统 - 接口幂等技术方案,高可用系统架构与技术选型

幂等概念来自于数学,在计算机科学中,幂等表示一次后、或多次请求某一资源,应该有同样的影响效果。 在业务表现上一般是同样的数据效果,下面就常用的业务场景,来聊聊幂等的技术方案。 ----------------- 数据层 ----------------- 索引与事务 根据业务需要,给表添加唯一索…

C++中执行shell命令,popen与system的区别

C中执行shell命令&#xff0c;popen与system的区别_c popen_Op_chaos的博客-CSDN博客 2.system system()函数执行过程&#xff1a; 1.fork一个子进程&#xff1b; 2.在子进程中调用exec函数去执行command&#xff1b; 3.在父进程中调用wait去等待子进程结束。 由于system没…

RHCE——二十一、Ansible模块

RHCE 一、Ansible的三个命令模块1、组成2、特点3、区别3.1 command、shell模块:3.2 raw模块 4、command模块4.1 参数表4.2 free_form参数 5、shell模块5.1 作用5.2 例25.3 script模块5.4 例3 6、raw模块6.1 参数6.2 例4 二、文件操作模块1、file 模块1.1 参数1.2 案例 2、copy …

【工作记录】springboot集成aop实现日志@20230918

springboot集成aop实现日志 1. 添加依赖 <!-- aop 依赖 --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId> </dependency>2. 定义注解 Target(ElementType.METHOD)…

windows 安装 MySQL 绿色版

windows 安装 MySQL 绿色版 下载 官网&#xff1a; MySQL下载页面&#xff1a; MySQL直接下载链接&#xff1a;https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.34-winx64.zip 安装 将下载的mysql.zip文件解压缩到指定目录 搜索 cmd 并以管理员身份运行 切换到…

【微信小程序开发】宠物预约医疗项目实战-注册实现

【微信小程序开发】宠物预约医疗项目实战-注册实现 第二章 宠物预约医疗项目实战-注册实现 文章目录 【微信小程序开发】宠物预约医疗项目实战-注册实现前言一、打开项目文件二、编写wxss代码2.1 什么是wxss2.2 配置主程序全局样式 三. 在sign文件下的wxml文件中编写如下代码并…

数字森林:无人机航测技术在林业调查中的应用

林业调查是林业工作的基础&#xff0c;对于森林资源的管理、规划、保护、经济发展和农业种植等方面都具有重要的意义。传统林业调查主要依赖人工进行&#xff0c;存在工作效率低、数据精度低、数据分析困难、受地形限制、无法实时监测等缺陷。 随着科技的不断发展&#xff0c;无…

最新Python大数据之Excel进阶

文章目录 Excel图表类型了解有哪些图表类型 Excel图表使用图表的创建方式利用固定数据区域创建图表编辑数据系列添加数据标签格式化图表 Excel数据透视表数据透视表对原始数据的要求创建数据透视表数据透视表字段布局将数据透视图变成普通图表 Excel图表类型 为了揭示数据规律…

Open3D 进阶(11)使用GMM-Tree算法对点云配准

GMM-Tree算法 一、算法原理1、主要函数2、参考文献二、代码实现三、结果展示1、点云初始位置2、配准后的位置四、测试数据本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、算法原理 1、

Windows 10 + Jenkins 2.4 安装插件时https 的证书问题及解决

本篇面临与解决的问题 本篇是在 Windows 10中安装Jenkins 2.414.1 &#xff0c; 在安装完成之后安装一些需要的插件&#xff0c; 可以在浏览器端安装插件的时候&#xff0c; 总是不成功&#xff0c; 控制台报以下错误&#xff1a; SEVERE h.model.UpdateCenter$DownloadJob#r…

枚举连通块拆贡献+容斥:ABC312G

https://atcoder.jp/contests/abc321/tasks/abc321_g 这种题都没看出来我要去退役了 看完题目&#xff0c;可以获得&#xff1a; 期望、连通块&#xff1a;显然拆贡献啊&#xff01; n ≤ 17 n\le 17 n≤17&#xff1a;这不明显状压&#xff1f;结合前面连通块&#xff0c;就…

润和软件HopeStage与华宇信息TAS应用中间件完成产品兼容性互认证

近日&#xff0c;江苏润和软件股份有限公司&#xff08;以下简称“润和软件”&#xff09;HopeStage 操作系统与北京华宇信息技术有限公司&#xff08;以下简称“华宇信息”&#xff09;TAS应用中间件软件完成产品兼容性测试。 测试结果表明&#xff0c;企业级通用操作系统Hope…

成都优优聚美团代运营具备专业团队!

美团代运营是美团旗下的一项服务&#xff0c;旨在帮助商家解决运营难题&#xff0c;提升业务效率和销售额。美团代运营的优势在于多方面&#xff0c;以下将详细介绍。 首先&#xff0c;美团代运营拥有庞大的流量入口。作为中国领先的消费服务平台&#xff0c;美团拥有海量的用户…

字符函数和字符串函数(C语言进阶)

字符函数和字符串函数 一.求字符串长度1.strlen 二.长度不受限制的字符串函数介绍1.strcpy2.strcat3.strcmp 前言 C语言中对字符和字符串的处理很是频繁&#xff0c;但是C语言本身是没有字符串类型的&#xff0c;字符串通常放在常量字符串中或者字符数组中。 字符串常量适用于那…

逆向学习路径

逆向学习路径 PC端手机端(Android) PC端 计算机操作系统C、C编程语言基础STL等库知识数据结构与算法汇编知识&#xff08;放在这里是因为前面学C、C的时候会有所涉及&#xff0c;学起来简单些&#xff09;windows apiwindows 驱动调试技术&#xff08;6、7有涉及&#xff09;软…

百度SEO优化技巧大揭秘(提高网站排名的必备SEO技术)

SEO优化技术介绍&#xff1a; SEO优化技术是指通过对网站的结构、内容、链接等方面进行优化&#xff0c;提高网站在搜索引擎中的排名&#xff0c;从而增加流量、提升品牌知名度和销售额。目前&#xff0c;在众多搜索引擎中&#xff0c;百度占据了国内搜索引擎市场的主导地位&a…