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;  //学校id
    private Integer projectId;  //项目id
    private Integer leafId;  //小节id
    private Integer leafTypeId;  //小节类型
    private Integer chapterId;  //章节id
    private 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> {

    // 定义一个全局变量用来保存所有连接的客户端Channel
    private static final Set<Channel> connectedChannels = Collections.newSetFromMap(new ConcurrentHashMap<>());

    // 当有新的连接时,将Channel添加到集合中
    public void handlerAdded(ChannelHandlerContext ctx) {
        connectedChannels.add(ctx.channel());
    }

    // 当连接关闭时,从集合中移除该Channel
    public void handlerRemoved(ChannelHandlerContext ctx) {
        connectedChannels.remove(ctx.channel());
    }

    @Override
    protected 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>() {
                    @Override
                    protected 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');
				});
			}

///--------------------------------------------------这是scoket
							let 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.mfbz.cn/a/776979.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

模型驱动开发(Model-Driven Development,MDD):提高软件开发效率与一致性的利器

目录 前言1. 模型驱动开发的原理1.1 什么是模型驱动开发1.2 MDD的核心思想 2. 模型驱动开发的优势2.1 提高开发效率2.2 确保代码一致性2.3 促进沟通和协作2.4 方便维护和扩展 3. 实现模型驱动开发的方法3.1 选择合适的建模工具3.1.1 UML3.1.2 BPMN3.1.3 SysML 3.2 建模方法3.2.…

解决使用PPIO欧派云服务器时无法使用sftp的问题

首先在对外TCP端口中选择22端口&#xff1a; 在连接-端口映射中可以看到&#xff1a; 使用ssh连接云服务器&#xff0c;更新包列表并安装OpenSSH服务器&#xff1a; apt-get update apt-get install-y openssh-server 创建 SSH 运行目录&#xff1a; mkdir /var/run/sshd 设…

springboot基于Java的超市进销存系统+ LW+ PPT+源码+讲解

第三章系统分析与设计 3.1 可行性分析 一个完整的系统&#xff0c;可行性分析是必须要有的&#xff0c;因为他关系到系统生存问题&#xff0c;对开发的意义进行分析&#xff0c;能否通过本网站来补充线下超市进销存管理模式中的缺限&#xff0c;去解决其中的不足等&#xff0c…

三叶青图像识别研究简概

三叶青图像识别研究总概 文章目录 前言一、整体目录介绍二、前期安排三、构建图像分类数据集四、模型训练准备五、迁移学习模型六、在测试集上评估模型精度七、可解释性分析、显著性分析八、图像分类部署九、树莓派部署十、相关补充总结 前言 本系列文章为近期所做项目研究而作…

Qt 网络编程 udp通信

学习目标&#xff1a;使用udp通信 前置环境 运行环境:qt creator 4.12 学习内容 UDP 协议基础知识 1、UDP(用户数据报协议)是轻量的、不可靠的、面向数据报、无连接的协议&#xff0c;用于可靠性要求不高的场合。两个应用程序之间进行UDP 通信不需先建立持久的 socket 连接…

基于STM32F407ZG的FreeRTOS移植

1.从FreeRTOS官网中下载源码 2、简单分析FreeRTOS源码目录结构 2.1、简单分析FreeRTOS源码根目录 &#xff08;1&#xff09;Demo&#xff1a;是官方为一些单片机移植FreeRTOS的例程 &#xff08;2&#xff09;License&#xff1a;许可信息 &#xff08;3&#xff09;Sourc…

大学教师门诊预约小程序-计算机毕业设计源码73068

摘要 在当今数字化、信息化的浪潮中&#xff0c;大学校园的服务管理正朝着智能化、便捷化的方向迈进。为了优化大学教师的医疗体验&#xff0c;提升门诊预约的效率和便捷性&#xff0c;我们基于Spring Boot框架设计并实现了一款大学教师门诊预约小程序。该小程序不仅提供了传统…

你的 Mac 废纸篓都生苍蝇啦

今天给大家推荐个免费且有趣的小工具 BananaBin&#xff0c;它可以在你的废纸篓上“长”一些可爱的苍蝇&#x1fab0;。 软件介绍 BananaBin 是 macOS 上的一款有趣实用工具&#xff0c;当你的垃圾桶满了时&#xff0c;它会提醒你清理。这个软件通过在垃圾桶上添加互动的苍蝇…

亲子时光里的打脸高手,贾乃亮与甜馨的父爱如山

贾乃亮这波操作&#xff0c;简直是“实力打脸”界的MVP啊&#xff01; 7月5号&#xff0c;他一甩手&#xff0c;甩出张合照&#xff0c; 瞬间让多少猜测纷飞的小伙伴直呼&#xff1a;“脸疼不&#xff1f;”带着咱家小甜心甜馨&#xff0c; 回了哈尔滨老家&#xff0c;这趟亲…

AI革命:RAG技术引领未来智能

AI革命:RAG技术引领未来智能 在人工智能的浪潮中,一种名为RAG(Retrieval-Augmented Generation)的技术正在悄然改变我们的世界。这种技术通过整合外部知识库,极大地增强了大型语言模型(LLM)的性能,为智能助手、聊天机器人等应用带来了革命性的提升。 1 突破性的RAG技…

停车场小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;车主管理&#xff0c;商家管理&#xff0c;停车场信息管理&#xff0c;预约停车管理&#xff0c;商场收费管理&#xff0c;留言板管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;停车场信息…

Java——IO流(二)-(4/7):不同编码读取乱码的问题,转换流-InputStreamReader、OutputStreamWriter

目录 不同编码读取出现乱码的问题 转换流 InputStreamReader(字符输入转换流) 实例演示(1) OutputStreamWriter(字符输出转换流) 实例演示(2) 不同编码读取出现乱码的问题 如果代码编码和被读取的文本文件的编码是一致的&#xff0c;使用字符流读取文本文件时不会出现乱…

ctfshow web入门 nodejs

web334 有个文件下载之后改后缀为zip加压就可以得到两个文件 一个文件类似于index.php 还有一个就是登录密码登录成功就有flag username:ctfshow password:123456因为 return name!CTFSHOW && item.username name.toUpperCase() && item.password passwor…

8分钟带你快速了解Connector/Catalog API的核心设计

引言 在现代大数据应用中&#xff0c;数据集成和同步成为企业数据管理的关键环节。随着数据源和数据库的多样化&#xff0c;如何高效地进行数据集成成为企业面临的重要挑战。 Apache SeaTunnel 作为一款开源的数据集成工具&#xff0c;致力于解决这一问题。本文将详细介绍 Sea…

Drools开源业务规则引擎(一)- 安装与介绍

文章目录 [toc] Drools开源业务规则引擎&#xff08;一&#xff09;- 安装与介绍0.何为规则引擎1.Drools介绍1.1.依赖模块1.2.规则引擎 2.Drools安装2.1.依赖导入2.2.规则的输入和输出类型输入类型输出类型 2.3.创建规则文件2.4.构建可执行规则库2.5.执行结果&#xff1a; 3.Dr…

Oracle Database 23ai新特性:增加聚合函数对INTERVAL数据类型支持

在Oracle早期的版本&#xff0c;聚合函数和分析函数MIN/MAX 就支持了INTERVAL 数据类型。但是&#xff0c;当我们使用SUM或AVG函数对INTERVAL 数据类型进行运算时&#xff0c;就会报错。 随着Oracle Database 23ai 的发布&#xff0c;增加了 AVG 以及 SUM 函数对INTERVAL 数据…

Keepalived+LVS实现负责均衡,高可用的集群

Keepalived的设计目标是构建高可用的LVS负载均衡群集&#xff0c;可以调用ipvsadm工具来创建虚拟服务器&#xff0c;管理服务器池&#xff0c;而不仅仅用作双机热备。使用Keepalived构建LVS群集更加简便易用&#xff0c;主要优势体现在&#xff1a;对LVS负责调度器实现热备切换…

七、MyBatis-Plus高级用法:最优化持久层开发-个人版

七、MyBatis-Plus高级用法&#xff1a;最优化持久层开发 目录 文章目录 七、MyBatis-Plus高级用法&#xff1a;最优化持久层开发目录 一、MyBatis-Plus快速入门1.1 简介1.2 快速入门回顾复习 二、MyBatis-Plus核心功能2.1 基于Mapper接口CRUDInsert方法Delete方法Update方法Se…

实战某大型连锁企业域渗透

点击星标&#xff0c;即时接收最新推文 本文选自《内网安全攻防&#xff1a;红队之路》 扫描二维码五折购书 实战域渗透测试流程 对黑客来说&#xff0c;拿下域控制器是终极目标。然而攻击者空间是如何通过采取信息收集、权限提升、横向移动等一系列手段&#xff0c;从而一步步…

Maven基本使用

1. Maven前瞻 Maven官网&#xff1a;https://maven.apache.org/ Maven镜像&#xff1a;https://mvnrepository.com 1.1、Maven是什么 Maven是一个功能强大的项目管理和构建工具&#xff0c;可以帮助开发人员简化Java项目的构建过程。 在Maven中&#xff0c;使用一个名为 pom.…