maven项目使用netty,前端是vue2,实现通讯

引入的java包

<!--        以下是即时通讯--><!-- Netty core modules  --><dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.76.Final</version> <!-- 使用最新的稳定版本 --></dependency><!-- Optional: Support for WebSocket --><dependency><groupId>io.netty</groupId><artifactId>netty-handler-proxy</artifactId><version>4.1.76.Final</version></dependency><!-- Optional: Support for HTTP/2 --><dependency><groupId>io.netty</groupId><artifactId>netty-resolver-dns-native-macos</artifactId><version>4.1.76.Final</version><classifier>osx-x86_64</classifier><optional>true</optional></dependency>

2.创建project对象(这个对象是跟业务相关的,如果业务简单,不创建也可以,最后传输的都是字符串)

@Getter
@Setter
public class Project {private GroupStudentService groupStudentService;private Integer schoolId;  //学校idprivate Integer projectId;  //项目idprivate Integer leafId;  //小节idprivate Integer leafTypeId;  //小节类型private Integer chapterId;  //章节idprivate Object currentLeaf;//当前小节private  Integer currentLeafIndex;//当前小节的下标private  Integer currentChapterIndex;//当前章节的下标public Project(Integer projectId,Integer leafId,Integer leafTypeId,Integer chapterId,Object currentLeaf,Integer currentLeafIndex,Integer currentChapterIndex,Integer schoolId) {this.projectId = projectId;this.leafId = leafId;this.leafTypeId = leafTypeId;this.chapterId = chapterId;this.currentLeaf = currentLeaf;this.currentLeafIndex = currentLeafIndex;this.currentChapterIndex = currentChapterIndex;this.schoolId= schoolId;}public Project() {}

3.创建WebsocketHandler

public class WebsocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {// 定义一个全局变量用来保存所有连接的客户端Channelprivate static final Set<Channel> connectedChannels = Collections.newSetFromMap(new ConcurrentHashMap<>());// 当有新的连接时,将Channel添加到集合中public void handlerAdded(ChannelHandlerContext ctx) {connectedChannels.add(ctx.channel());}// 当连接关闭时,从集合中移除该Channelpublic void handlerRemoved(ChannelHandlerContext ctx) {connectedChannels.remove(ctx.channel());}@Overrideprotected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) {String text = msg.text();String prefix = text.substring(0, 7); //截取前缀if (prefix.contains("switch")) {//当前数据是切换小节handleSwitch(text.substring(7));} else if (prefix.contains("xsData")) {//当前数据是学生提交作业给老师的handleStudentData(text.substring(7));}}//这个是专门用来切换小节的,老师切换上一节,下一节,跳到指定小节,学生的大屏页面也跟着切换private void handleSwitch(String parts) {//把parts转成jsonobject对象JSONObject jsonObject = JSON.parseObject(parts);Integer projectId = (int) jsonObject.get("projectId");Integer leafId = (int) jsonObject.get("leafId");Integer leafTypeId = (int) jsonObject.get("leafTypeId");Integer chapterId = (int) jsonObject.get("chapterId");Integer currentLeafIndex = (int) jsonObject.get("currentLeafIndex");Integer currentChapterIndex = (int) jsonObject.get("currentChapterIndex");Object currentLeaf = jsonObject.get("currentLeaf");Integer schoolId = (int) jsonObject.get("institutionId");Project project = new Project(projectId,leafId,leafTypeId,chapterId,currentLeaf,currentLeafIndex,currentChapterIndex, schoolId);Gson gson = new Gson();String jsonProject = gson.toJson(project);if (project != null) {for (Channel channel : connectedChannels) {if (channel.isActive()) { // 检查通道是否仍然活跃channel.writeAndFlush(new TextWebSocketFrame("switch:" + jsonProject));}}}}//这个是专门用来学生提交数据的,学生提交数据,老师大屏上能展示数据private void handleStudentData(String parts) {//把parts转成jsonobject对象JSONObject jsonObject = JSON.parseObject(parts);Integer projectId =Integer.valueOf(jsonObject.get("projectId").toString());Integer leafId = Integer.valueOf(jsonObject.get("leafId").toString());Integer schoolId = Integer.valueOf( jsonObject.get("institutionId").toString());Project project = new Project();project.setProjectId(projectId);project.setSchoolId(schoolId);project.setLeafId(leafId);Gson gson = new Gson();String jsonProject = gson.toJson(project);if (project != null) {for (Channel channel : connectedChannels) {if (channel.isActive()) { // 检查通道是否仍然活跃channel.writeAndFlush(new TextWebSocketFrame("xsData:" + jsonProject));}}}}

4.创建WebsocketServer启动类

public class WebsocketServer {public static void main(String[] args) throws InterruptedException {initWebsocket();}public static void initWebsocket() throws InterruptedException {EventLoopGroup bossGroup = new NioEventLoopGroup();EventLoopGroup workerGroup = new NioEventLoopGroup();try {ServerBootstrap b = new ServerBootstrap();b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) {System.out.println("初始化WebsocketServer");ChannelPipeline p = ch.pipeline();p.addLast(new HttpServerCodec());p.addLast(new HttpObjectAggregator(65536));p.addLast(new ChunkedWriteHandler());p.addLast(new WebSocketServerProtocolHandler("/screen"));p.addLast(new WebsocketHandler());}});ChannelFuture f = b.bind(8084).sync();f.channel().closeFuture().sync();} finally {workerGroup.shutdownGracefully();bossGroup.shutdownGracefully();}}}

5.页面上的发送数据

connectWebSocket() {this.socket = new WebSocket('ws://' + window.location.hostname + ':8084/screen');this.socket.addEventListener('open', (event) => {console.log('WebSocket connection opened--学生');});this.socket.addEventListener('message', (event) => {console.log(event);});this.socket.addEventListener('error', (event) => {console.error('WebSocket error:', event);});this.socket.addEventListener('close', (event) => {console.log('WebSocket connection closed');});}

///--------------------------------------------------这是scoketlet sendData = {projectId: this.projectId,leafId: this.leafId,institutionId: JSON.parse(localStorage.getItem('user')).institutionId};console.log(sendData)// 将数据对象转化为JSON字符串let jsonData = JSON.stringify(sendData);let prefixedData = 'xsData:' + jsonData;this.socket.send(prefixedData);///----------------------------------------------------------------

6.页面上接收数据

initWebSocket() {this.socket = new WebSocket(`ws://${window.location.hostname}:8084/screen`);this.socket.addEventListener('open', (event) => {console.log('WebSocket connection opened');});this.socket.addEventListener('message', (event) => {const data = event.data;if (data.startsWith('xsData:')) {const jsonData = data.substring(7);const vo = JSON.parse(jsonData);if (vo.schoolId == JSON.parse(localStorage.getItem('user')).institutionId &&vo.projectId == this.projectId && vo.leafId == this.leafId) {this.getQd();} else {console.log("无效信息")}}});this.socket.addEventListener('error', (event) => {console.error('WebSocket error:', event);});this.socket.addEventListener('close', (event) => {console.log('WebSocket connection closed');});},

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

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

相关文章

C++初学者指南-4.诊断---地址检测器

C初学者指南-4.诊断—地址检测器 幻灯片 地址检测器&#xff08;ASan&#xff09; 适用编译器g,clang检测内存错误 内存泄露访问已经释放的内存访问不正确的堆栈区域 用额外的指令检测代码 运行时间增加约70%内存使用量大约增加了3倍 示例&#xff1a;检测空指针 使用地址…

中英双语介绍百老汇著名歌剧:《猫》(Cats)和《剧院魅影》(The Phantom of the Opera)

中文版 百老汇著名歌剧 百老汇&#xff08;Broadway&#xff09;是世界著名的剧院区&#xff0c;位于美国纽约市曼哈顿。这里汇集了许多著名的音乐剧和歌剧&#xff0c;吸引了全球各地的观众。以下是两部百老汇的经典音乐剧&#xff1a;《猫》和《剧院魅影》的详细介绍。 1.…

拉普拉斯逆变换

https://www.bilibili.com/video/BV17i4y1475Y?p21&vd_source2e6b4ba548ec9462b2f9633ff700e9b9 CV 17 陈永平教授关于拉普拉斯逆变换的式子的推导 最关键的两步 想到取一个合适的contour L R L_R LR​部分是实部 γ \gamma γ要大于所有极点的实部,这样就可以搞一个大…

SCI二区TOP|麋鹿群优化算法: 一种新颖的受自然启发的元启发式算法

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献5.代码获取 1.背景 2024年&#xff0c;SO Oladejo受到麋鹿群的繁殖过程启发&#xff0c;提出了麋鹿群优化算法&#xff08;Elk herd optimizer, EHO&#xff09;。 2.算法原理 2.1算法思想 EHO灵感来自麋鹿…

C语言编程与进阶

1.0 C语言关键字 1-1C语言关键字-CSDN博客文章浏览阅读831次&#xff0c;点赞13次&#xff0c;收藏24次。define使用define定义常量return 0;使用define定义宏// define 定义宏&#xff0c;名字是ADD(x,y),x y 是宏的参数int a 10;int b 20;return 0;宏定义的本质是替换&am…

pandas读取CSV格式文件生成数据发生器iteration

背景 数据集标签为csv文件格式&#xff0c;有三个字段column_hander [‘id’, ‘boneage’, ‘male’]&#xff0c;需要自己定义数据集。文件较大&#xff0c;做一个数据发生器迭代更新数据集。 实现模板 在Pandas中&#xff0c;可以使用pandas.read_csv函数读取CSV文件&…

ShardingSphere实战

ShardingSphere实战 文章目录 ShardingSphere实战分库分表实战建表建表sql利用存储过程建表Sharding-jdbc分库分表配置 基于业务的Sharding-key考虑订单id用户id分片策略订单id的设计与实现**设计思想**&#xff1a;设计思路&#xff1a; 具体分片策略实现测试数据插入商户商品…

推荐好玩的工具之OhMyPosh使用

解除禁止脚本 Set-ExecutionPolicy RemoteSigned 下载Oh My Posh winget install oh-my-posh 或者 Install-Module oh-my-posh -Scope AllUsers 下载Git提示 Install-Module posh-git -Scope CurrentUser 或者 Install-Module posh-git -Scope AllUser 下载命令提示 Install-Mo…

SwinUnet详解

文章目录 摘要一. 编码端模块1. PatchEmbed2. SwinTransformerBlock2.1. Window_partition2.2. WindowAttention2.3. Window_reverse2.4. MLP 3. PatchMerging 二. 解码端模块三. 完整流程图 摘要 swinunet基本结构&#xff1a; swinunet采用编码器-解码器结构&#xff1a; 编…

2.1 tmux和vim

文章目录 前言概述tmuxvim总结 前言 开始学习的时间是 2024.7.6 ,13&#xff1a;47 概述 最好多使用&#xff0c;练成条件反射式的 直接使用终端的工具&#xff0c;可以连接到服务器&#xff0c;不需要使用本地的软件 tmux 这个主要有两个功能&#xff0c;第一个功能是分…

Linux多进程和多线程(七)进程间通信-信号量

进程间通信之信号量 资源竞争 多个进程竞争同一资源时&#xff0c;会发生资源竞争。 资源竞争会导致进程的执行出现不可预测的结果。 临界资源 不允许同时有多个进程访问的资源, 包括硬件资源 (CPU、内存、存储器以及其他外 围设备) 与软件资源(共享代码段、共享数据结构) …

Redis Cluster 模式 的具体实施细节是什么样的?

概述 参考&#xff1a;What are Redis Cluster and How to setup Redis Cluster locally ? | by Rajat Pachauri | Medium Redis Cluster 的工作原理是将数据分布在多个节点上&#xff0c;同时确保高可用性和容错能力。以下是 Redis Cluster 运行方式的简要概述&#xff1a; …

读书到底有什么意义?从笨小孩到名人的逆袭之路

点击上方△腾阳 关注 作者 l 腾阳 转载请联系授权 读书到底有什么意义&#xff1f; 有一个鸟语花香的农场里&#xff0c;住着老农夫和他的小孙子。 老农夫经常在清晨会坐在窗边&#xff0c;捧着厚厚的《圣经》&#xff0c;沉浸在知识的海洋里。 小孙子问他&#xff1a;…

VSCode设置好看清晰的字体!中文用鸿蒙,英文用Jetbrains Mono

一、中文字体——HarmonyOS Sans SC 1、下载字体 官网地址&#xff1a;https://developer.huawei.com/consumer/cn/design/resource/ 直接下载&#xff1a;https://communityfile-drcn.op.dbankcloud.cn/FileServer/getFile/cmtyPub/011/111/111/0000000000011111111.20230517…

Redis分布式锁的应用场景有哪些

⼀ 、应⽤场景 在多线程并发的场景下 &#xff0c;Java Synchronized/Reentrantlock 锁能够实现同⼀个JVM进程内多线程 并发的安全性 &#xff0c;但⽆法保证多个JVM进程实例构成的集群环境在多线程下的安全性。在⼀些业务场景 下需要引⼊分布式锁。 1、缓存击穿 当某个热点缓…

加密(3)非对称加密

一、介绍 1、概念 非对称加密&#xff0c;又称现代加密算法&#xff0c;非对称加密是计算机通信安全的基石&#xff0c;保证了加密数据不会被破解。加密和解密使用的是两个不同的密钥&#xff0c;这种算法叫作非对称加密算法。 2、示例 首先生成密钥对, 公钥为(5,14)&#…

【分布式系统】ELK 企业级日志分析系统

目录 一.ELK概述 1.简介 1.1.可以添加的其他组件 1.2.filebeat 结合 logstash 带来好处 2.为什么使用ELK 3.完整日志系统基本特征 4.工作原理 二.部署ELK日志分析系统 1.初始化环境 2.完成JAVA部署 三. ELK Elasticsearch 集群部署 1.安装 2.修改配置文件 3.es 性…

latex英文转中文word,及一些latex相关工具分享

前言&#xff1a;想要转换latex生成的英文pdf文件为中文word文件 一、主要步骤 1、文字翻译&#xff1a;直接使用谷歌翻译等辅助将英文翻译成中文即可&#xff1b; **2、图片&#xff1a;**使用latex时一般保存的.png&#xff0c;.bmp格式图片可以直接插入word, 但是.eps或者…

Vue3:全局播放背景音乐

说明&#xff1a;一个全局播放的背景音乐&#xff0c;首页无音乐无音乐图标&#xff0c;在首页互动跳转页面并开始播放音乐&#xff0c;切换页面不需暂停音乐也不会重置音乐&#xff0c;可以通过音乐图标控制暂停或播放。 MusicPlay.vue&#xff08;音乐组件&#xff09; <…

Sentinel限流算法总结

文章目录 一、线程隔离二、滑动窗口算法三、令牌桶算法四、漏桶算法 一、线程隔离 线程隔离有两种方式实现&#xff1a; 线程池隔离&#xff1a;给每个服务调用业务分配一个线程池&#xff0c;利用线程池本身实现隔离效果信号量隔离&#xff1a;不创建线程池&#xff0c;而是…