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

Autoxjs 实践-Spring Boot 集成 WebSocket

概述

最近弄了福袋工具,由于工具运行中,不好查看福袋结果,所以我想将福袋工具运行数据返回到后台,做数据统计、之后工具会越来越多,就弄了个后台,方便管理。

实现效果

在这里插入图片描述

在这里插入图片描述

WebSocket?

websocket是一种在单个TCP连接上进行全双工通讯的协议,websocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据,在websocket中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

简单来说:WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。

Autoxjs + Springboot + Websocket通用版

集成分为三步:添加依赖、增加配置类和消息核心类、Autoxjs集成。

maven 添加依赖

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

WebSocket配置类

@Configuration
public class WebSocketConfig{@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}}

消息核心类WebSocketServer

@ServerEndpoint("/websocket/{adminId}")
@Component
public class WebSocketMessage{/** 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。 */private static int onlineCount = 0;/** concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识 */private static CopyOnWriteArraySet<WebSocketMessage> webSocketSet = new CopyOnWriteArraySet<WebSocketMessage>();/** 与某个客户端的连接会话,需要通过它来给客户端发送数据 */private Session session;protected static final Logger logger = LoggerFactory.getLogger(WebSocketMessage.class);/** 用户ID*/private String adminId;/*** 连接建立成功调用的方法* @param session  可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据*/@OnOpenpublic void onOpen(Session session, @PathParam("adminId") String adminId) throws IOException{//重复标识//boolean isFlay = true;for(WebSocketMessage item: webSocketSet){if(adminId.equals(item.adminId)){item.onClose();//isFlay = false;//break;}}this.session = session;this.adminId = adminId;webSocketSet.add(this);     //加入set中addOnlineCount();           //在线数加1logger.info("有新连接加入!当前在线人数为" + getOnlineCount() + "用户id:"+adminId);}/*** 连接关闭调用的方法*/@OnClosepublic void onClose(){webSocketSet.remove(this);  //从set中删除subOnlineCount();           //在线数减1    logger.info("有一连接关闭!当前在线人数为" + getOnlineCount());}/*** 收到客户端消息后调用的方法* @param message 客户端发送过来的消息* @param session 可选的参数*/@OnMessagepublic void onMessage(String message, Session session) {logger.info("来自客户端的消息:" + message);}/*** 发生错误时调用* @param session* @param error*/@OnErrorpublic void onError(Session session, Throwable error){logger.info("发生错误:"+error.getMessage());error.printStackTrace();}/*** 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。* @param message* @throws IOException*/public void sendMessage(String message) throws IOException{this.session.getBasicRemote().sendText(message);//this.session.getAsyncRemote().sendText(message);}/*** * @Description 获取在线人数* @Date 2019年8月6日 下午2:29:37* @Author Jly* @return*/public static synchronized int getOnlineCount() {return onlineCount;}/*** * @Description 添加在线人数* @Date 2019年8月6日 下午2:30:01* @Author Jly*/public static synchronized void addOnlineCount() {WebSocketMessage.onlineCount++;}/*** * @Description 减少在线人数* @Date 2019年8月6日 下午2:30:18* @Author Jly*/public static synchronized void subOnlineCount() {WebSocketMessage.onlineCount--;}/*** 测试页面接受信息* @param adminId* @param message*/public static void sendDataMessage(String adminId, String message){//群发消息for(WebSocketMessage item: webSocketSet){             try {if(adminId.equals(item.adminId)){item.sendMessage(message);}} catch (IOException e) {e.printStackTrace();continue;}}}
}

autoxJs webSocket

importPackage(Packages["okhttp3"]); //导入包
var globalWebsocket = null;
var client = new OkHttpClient.Builder().retryOnConnectionFailure(true).build();
// 需要根据自己改IP
var request = new 
Request.Builder().url("ws://192.168.0.91:8080/websocket/349075715535306752").build(); //vscode  插件的ip地址,
client.dispatcher().cancelAll();//清理一次
myListener = {onOpen: function (result, response) {console.log("连接成功");globalWebsocket = result},onMessage: function (webSocket, msg) { //msg可能是字符串,也可能是byte数组,取决于服务器送的内容print("msg");print(msg);},onClosing: function (webSocket, code, response) {print("正在关闭");},onClosed: function (webSocket, code, response) {print("已关闭");},onFailure: function (webSocket, t, response) {print("错误");}
}
function init() {webSocket = client.newWebSocket(request, new WebSocketListener(myListener)); //创建链接
}
function run() {try {if (globalWebsocket == null) {init();sleep(500)} else {var json = {};json.command = "PING"let success = globalWebsocket.send(JSON.stringify(json))if (!success) {console.log("发送失败")}sleep(1000)}} catch (e) {console.log(e)}
}
//发送心跳
threads.start(function () {setInterval(() => {run()}, 30 * 1000);
})

总结

资源仅为学习参考!!

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • NMF算法
  • el-input中change事件造成的坑
  • AI大数据处理与分析实战--体育问卷分析
  • 评价GPT-4的方案
  • blender从视频中动作捕捉,绑定到人物模型
  • 【调度算法】Boltzmann选择
  • Spring Boot 实现动态数据源配置
  • 嵌入式中C语言经典的面试题分享
  • 《TCP/IP网络编程》(第十三章)多种I/O函数(2)
  • GPT-4欺骗人类的惊人成功率达99.16%!
  • 华为坤灵路由器配置SSH
  • LeetCode 2356, 238, 141
  • 1025 反转链表
  • 大模型PEFT(二) 之 大模型LoRA指令微调实践
  • 【软件工程】第六章
  • ES6指北【2】—— 箭头函数
  • es6要点
  • Facebook AccountKit 接入的坑点
  • javascript面向对象之创建对象
  • mysql常用命令汇总
  • 道格拉斯-普克 抽稀算法 附javascript实现
  • 得到一个数组中任意X个元素的所有组合 即C(n,m)
  • 第2章 网络文档
  • 番外篇1:在Windows环境下安装JDK
  • 让你成为前端,后端或全栈开发程序员的进阶指南,一门学到老的技术
  • 说说动画卡顿的解决方案
  • 我从编程教室毕业
  • 字符串匹配基础上
  • [地铁译]使用SSD缓存应用数据——Moneta项目: 低成本优化的下一代EVCache ...
  • raise 与 raise ... from 的区别
  • 继 XDL 之后,阿里妈妈开源大规模分布式图表征学习框架 Euler ...
  • ‌JavaScript 数据类型转换
  • #NOIP 2014# day.1 生活大爆炸版 石头剪刀布
  • #微信小程序(布局、渲染层基础知识)
  • (非本人原创)史记·柴静列传(r4笔记第65天)
  • (附源码)ssm高校社团管理系统 毕业设计 234162
  • (附源码)计算机毕业设计大学生兼职系统
  • (十六)串口UART
  • (顺序)容器的好伴侣 --- 容器适配器
  • (转)memcache、redis缓存
  • (转)如何上传第三方jar包至Maven私服让maven项目可以使用第三方jar包
  • *Algs4-1.5.25随机网格的倍率测试-(未读懂题)
  • *Django中的Ajax 纯js的书写样式1
  • .NET基础篇——反射的奥妙
  • .NET技术成长路线架构图
  • .NET中的Event与Delegates,从Publisher到Subscriber的衔接!
  • @angular/cli项目构建--Dynamic.Form
  • @entity 不限字节长度的类型_一文读懂Redis常见对象类型的底层数据结构
  • @Transactional事务注解内含乾坤?
  • [ vulhub漏洞复现篇 ] Celery <4.0 Redis未授权访问+Pickle反序列化利用
  • [ vulhub漏洞复现篇 ] ThinkPHP 5.0.23-Rce
  • [android] 切换界面的通用处理
  • [C/C++]关于C++11中的std::move和std::forward
  • [C++][ProtoBuf][初识ProtoBuf]详细讲解
  • [codevs] 1029 遍历问题