Autoxjs 实践-Spring Boot 集成 WebSocket

news2024/11/24 18:52:17

概述

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

实现效果

在这里插入图片描述

在这里插入图片描述

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{

    @Bean
    public 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为与某个客户端的连接会话,需要通过它来给客户端发送数据
     */
    @OnOpen
    public 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();           //在线数加1
	    logger.info("有新连接加入!当前在线人数为" + getOnlineCount() + "用户id:"+adminId);
    }
     
    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(){
        webSocketSet.remove(this);  //从set中删除
        subOnlineCount();           //在线数减1    
        logger.info("有一连接关闭!当前在线人数为" + getOnlineCount());
    }
     
    /**
     * 收到客户端消息后调用的方法
     * @param message 客户端发送过来的消息
     * @param session 可选的参数
     */
    @OnMessage
    public void onMessage(String message, Session session) {
    	logger.info("来自客户端的消息:" + message);
    }
     
    /**
     * 发生错误时调用
     * @param session
     * @param error
     */
    @OnError
    public 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);
})

总结

资源仅为学习参考!!

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

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

相关文章

【JavaEE初阶系列】——Cookie和Session应用之实现登录页面

目录 &#x1f6a9;本章目标 1.登录页面 2.servlet处理上述的登录请求 3.网站主页(成功登录之后的页面&#xff09; &#x1f6a9;实现过程 &#x1f393;登录页面 &#x1f393;Servlet处理登录请求 &#x1f388;获取请求传来的参数(用户名和密码) &#x1f388;验证…

Electron学习笔记(五)

文章目录 相关笔记笔记说明 七、系统1、系统对话框2、自定义窗口菜单3、系统右键菜单4、快捷键(1)、监听网页按键事件 &#xff08;窗口需处于激活状态&#xff09;(2)、监听全局按键事件 &#xff08;窗口无需处于激活状态&#xff09;(3)、补充&#xff1a;自定义窗口菜单快捷…

Three.js基础练习——渲染一个立方体

1.学习内容参考了 three.js入门教程--零基础也能学会_threejs菜鸟教程-CSDN博客 本章内容包含渲染立方体&#xff0c;并配合ui工具食用~ 2.效果图 import * as THREE from three import * as dat from dat.gui import { OrbitControls } from three/addons/controls/OrbitC…

【网站项目】SpringBoot803房屋租赁管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

【Golang】VSCode进行GO的调试

原来的launch.json {"version": "0.2.0","configurations": [{"name": "Golang","type": "go","request": "launch","program": "${workspaceFolder}","…

Linux技术---部署PXE服务器实现批量安装操作系统

部署PXE服务器实现批量安装操作系统 部署PXE服务器实现批量安装操作系统 部署PXE服务器实现批量安装操作系统1.安装相关服务组件1.1 安装tftp和xinetd1.2 安装DHCP服务1.3 准备 Linux 内核、初始化镜像文件、 PXE 引导程序、安装FTP服务并准备安装源1.4 配置启动菜单文件1.5 验…

JVM之运行时数据区

Java虚拟机在运行时管理的内存区域被称为运行时数据区。 程序计数器&#xff1a; 也叫pc寄存器&#xff0c;每个线程会通过程序计数器记录当前要执行的字节码指令的地址。程序计数器在运行时是不会发生内存溢出的&#xff0c;因为每个线程只存储一个固定长度的内存地址。 JAVA虚…

[蓝桥杯 2021 国 ABC] 123(java)——前缀和,思维

目录 题目 解析 代码 这么久了&#xff0c;我终于能不看别人代码完整写出来了&#xff0c;呜呜呜。虽然过程也是很曲折。 题目 解析 这个题&#xff0c;找其中数列的规律&#xff0c;1,1,2,1,2,3,1,2,3,4&#xff0c;...&#xff0c;因此我们把拆分成行列&#xff0c;如下…

Qt---信号和槽

一、信号和槽机制 所谓信号槽&#xff0c;实际就是观察者模式。当某个事件发生之后&#xff0c;比如&#xff0c;按钮检测到自己被点击了一下&#xff0c;它就会发出一个信号&#xff08;signal&#xff09;。这种发出是没有目的的&#xff0c;类似广播。如果有对象对这个信号…

车载测试和传统测试有什么区别

搞清楚车载测试和传统应用测试的区别,就可以大胆冲冲冲! 车载测试随着市场的需求量增加又火来一波,一直’遥遥领先’的我们一定要告诉大家一个事实:车载测试和传统的应用测试是有很大区别的. 测试对象不一样 传统测试:测试的对象无非就是各种应用,比如电脑端的web系统(使用浏…

Git系列:git tag 使用技巧

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

FANUC机器人坐标系的分类和简介

1、概述 坐标系是为了确定机器人的位置和姿势而在机器人或空间上定义的位置指标系统&#xff0c;坐标系分为关节坐标系和直角坐标系&#xff0c;直角坐标系遵循右手定则&#xff0c;而关节坐标系则是以机器人每个轴所转动的角度来表示机器人当前的位置。 2、坐标系的分类及简…

weblogic 反序列化 CVE-2018-2628

这个漏洞因为java版本问题一直下载不了ysoserial反序列化工具&#xff0c;没办法生成payload。这里记录一下漏洞原理。 一、漏洞简介 Weblogic Server中的RMI 通信使用T3协议在Weblogic Server和其它Java程序&#xff08;客户端或者其它Weblogic Server实例&#xff09;之间传…

团结引擎+OpenHarmony 3 通信

团结引擎和鸿蒙之间通信 因为 ts 并没有像 JAVA 有反射的调用&#xff0c;所以我们必须要像 Web GL 平台一样通过导出的行为告诉引擎到底哪些 ts 的接口可以给 C# 来调用。 1 在 Tuanjie 引擎里 需要一个tsllib文件&#xff0c;用于设置给导出对象 C#使用。就可以直接创建以 …

Unity基础

概述 基础知识 3D教学 数学计算公共类Mathf 练习: 三角函数 练习&#xff1a; Unity中的坐标系 Vector3向量 向量模长和单位向量 向量加减乘除 练习&#xff1a; 向量点乘 向量叉乘 向量插值运算 Quaternion四元数 为何要使用四元数 四元数是什么 四元数常用方法 四元数计算 练…

GeoServer安装以及部署

GeoServer介绍 GeoServer是一个开源的服务器软件&#xff0c;用于共享和编辑地理空间数据。它支持多种地理空间数据格式&#xff0c;并且可以发布为多种服务格式&#xff0c;如Web Feature Service (WFS)、Web Map Service (WMS)、Web Coverage Service (WCS)&#xff0c;以及…

十二、Redis主从复制

与其他的中间件存在同样的问题&#xff0c;在单机的情况&#xff0c;随着业务的增长&#xff0c;会面临着灾备、性能方面的压力。Redis在这方面提供了一主一从、一主多从的结构。这种结构同时也是实现读写分离功能的基础。即主节点提供写能力&#xff0c;从节点提供读能力。为了…

【C/C++】C/C++ 车票售票系统设计与实现(源码+课件)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

初识C语言——第十八天

循环while/do while while 语法结构 while(表达式) 循环语句; break:在while循环中&#xff0c;break用于永久的终止循环 continue:在while循环中&#xff0c;continue的作用是跳过本次循环continue后面的代码 直接去判断部分&#xff0c;看是否进行下一次循环。 注意事项…

射频识别技术RFID

射频识别技术RFID RFID介绍 射频识别&#xff1a; 英文名称是(Radio Frequency Identification)&#xff0c; 简称是“ RFID” 又称 无线射频识别&#xff0c; RFID是物联网的其中一种终端技术。 RFID是一种通信技术&#xff0c; 可通过无线电讯号耦合识别特定目标并读写相关…