Netty实现websocket且实现url传参的两种方式(源码分析)

news2024/12/23 1:33:34

1、先构建基本的netty框架

再下面的代码中我构建了一个最基本的netty实现websocket的框架,其他个性化部分再自行添加。

@Slf4j
public class TeacherServer {

    public void teacherStart(int port) throws InterruptedException {
        NioEventLoopGroup boss = new NioEventLoopGroup();
        NioEventLoopGroup worker = new NioEventLoopGroup(2);
    try{
        ServerBootstrap serverBootstrap = new ServerBootstrap()
                .group(boss, worker)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel nsc) throws Exception {
                        //http的编解码器
                        nsc.pipeline().addLast(new HttpServerCodec());
                        //将多个快组成一个完整的http请求
                        nsc.pipeline().addLast(new HttpObjectAggregator(65536));
                        nsc.pipeline().addLast(new WebSocketServerProtocolHandler("/teacher", null, true, 65536 * 10,false,true));
                    }
                });
        ChannelFuture cf = serverBootstrap.bind(port).sync();
        log.info("教师服务已开启");
        cf.channel().closeFuture().sync();
    } finally {
        boss.shutdownGracefully().sync(); // 释放线程池资源
        worker.shutdownGracefully().sync();
    }
    }

    //初始化
    public void init(int port){
    //异步启动
        new Thread(() -> {
            try {
                teacherStart(port);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }
}

要实现websocket并且实现url传参,我们需要关注WebSocketServerProtocolHandler处理的一个参数:checkStartsWith

这个参数我们需要把他设置成ture,为什么呢,让我们来看一下源码isWebSockerPath(),这方法是判断具体的url是否和我设置的路径相匹配:

可以看出如果checkStartWith设为false的话,则必须url和websocketPath相等,否则会返回false。如果设置为true的话则只需要websocketPath是具体的url的前缀就行。当最后返回false时,连接就无法建立。

我们看源码这是一个处理类WebSocketServerProtocolHandshakeHandler,这是WebSocketServerProtocolHandler这个处理类再创建的时候给加pipelien()里的的,放在其之前,专门用来处理握手的处理器。可以看到如果返回false,则不会接下来进行握手操作,而是直接将消息返回给下一个处理器。如果这样的话我们可以认为连接已经失败。

所以我们如果要通过url传参的话再构建WebSocketServerProtocolHandler对象时要将chaekStartWith设为true。

2、获取url中的传参

        2.1 再没建立连接前获取url

        因为websocket发起建立连接用的时http协议并携带升级协议的请求,后面服务端进行升级,将其升为websocket,那么我们可以再还未升级前,也就是再WebSocketServerProtocolHandler处理器前再新增一个处理器,读取第一次发起的http请求。再其中获取url,等获取到初始化完后将这个处理器从pipelien中移除

FullRequest是一个Java类,它表示一个完整的HTTP请求,包含请求方法、路径、头部和内容。它是Netty框架中的一个组件,用于处理网络通信。

public class TeacherContineHandler extends ChannelInboundHandlerAdapter {

 

    @Override
    public void channelRead(ChannelHandlerContext channelHandlerContext, Object msg) throws Exception {
        if (msg instanceof FullHttpRequest){
            FullHttpRequest request = (FullHttpRequest) msg;
            String uri = request.uri();
           /*
            *再这里编写自己的操作
            */
            // 在本channel上移除这个handler消息处理,即只处理一次,鉴权通过与否
            channelHandlerContext.pipeline().remove(TeacherContineHandler.class);
        }
        super.channelRead(channelHandlerContext, msg);
    }
}

ps:主要放置顺序: 

2.2 建立后通过自定义事件HandshakeComplete获取url 

其实netty已经为我们想好了,我也是看源码才发现的,再连接建立完成后WebSocketServerProtocolHandshakeHandler会响应一个事件,再这个事件里我们可以获取到我们想要的请求路径和请求头,我们通过这个方法不光可以再url上传参,还能通过请求头传参。

 其中我们通过一个 那个futre对象,就是握手方法返回的,该对象是一个异步的操作结果,可以在完成时触发回调函数。当其完成时我们通过这个对象判断是否成功握手。如果握手成功,那么就调用localHandshakePromise的trySuccess方法,表示握手成功,并调用ctx.fireUserEventTriggered方法,触发两个用户自定义的事件,分别是:

  • ServerHandshakeStateEvent.HANDSHAKE_COMPLETE,表示握手完成的状态事件。
  • HandshakeComplete,表示握手完成的具体信息,包括req.uri()、req.headers()和handshaker.selectedSubprotocol(),分别表示WebSocket的URI地址、HttpRequest的头信息和选择的子协议。

那我们就可以通过监听这个用户自定义事件来获取请求体了。具体做法就是我们需要实现userEventTriggered()方法这个方法就是用来再有用户自定义事件发生时被调用的,

具体实现如下:

public class TeacherWebSocketHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof WebSocketServerProtocolHandler.HandshakeComplete){
            WebSocketServerProtocolHandler.HandshakeComplete handshakeComplete = (WebSocketServerProtocolHandler.HandshakeComplete) evt;
            String s = handshakeComplete.requestUri();
            HttpHeaders entries = handshakeComplete.requestHeaders();
            /**
             * 实现自己的初始化操作
             */
        }
        super.userEventTriggered(ctx, evt);
    }
}

3、项目启动

我们的启动代码就写在main方法当中,再这个方法进行初始化,记得传入你想监听的端口,如果你想监听多个端口,可以安这样的步骤之间重复再写一遍就行,因为是异步启动的。

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

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

相关文章

视频录制工具有哪些?收藏起来,需要的时候用起来

视频录制工具顾名思义&#xff1a;用于捕获视频片段的软件。使用视频录制工具&#xff0c;你可以创建属于自己的视频内容。市面上的录屏工具五花八门&#xff0c;有哪些才是适合自己的呢&#xff1f; 虽然有许多视频录制工具可供选择&#xff0c;甚至有很多是免费的&#xff0…

Linux使用宝塔面板+Discuz+cpolar内网穿透工具搭建可公网访问论坛

Linux宝塔面板搭建Discuz论坛&#xff0c; 并内网穿透实现公网访问 文章目录 Linux宝塔面板搭建Discuz论坛&#xff0c; 并内网穿透实现公网访问前言1.安装基础环境2.一键部署Discuz3.安装cpolar工具4.配置域名访问Discuz5.固定域名公网地址6.配置Discuz论坛 前言 Crossday Di…

圈子社交系统丨论坛丨实名认证丨语音聊天丨VIP会员丨活动报名丨商城丨APP小程序h5丨源码交付,支持二开

圈子社交系统丨论坛丨实名认证丨语音聊天丨VIP会员丨活动报名丨商城丨APP小程序h5 后端下载地址&#xff1a;圈子系统APP源码&#xff0c;婚恋小程序&#xff0c;APP&#xff0c;H5&#xff0c;表白墙源码&#xff0c;恋爱小程序APP&#xff0c;交友APP小程序&#xff0c;社交小…

多线程 02

1.线程的常见构造方法 方法说明Thread()创建线程对象Thread(Runnable target)使用 Runnable 对象创建线程对象Thread(String name)创建线程对象&#xff0c;并命名Thread(Runnable target, String name)使用 Runnable 对象创建线程对象&#xff0c;并命名【了解】Thread(Threa…

数据库实验7

实验报告&#xff08;七&#xff09;数据更新 1、实验目的 &#xff08;1&#xff09; 掌握插入、更新和删除表数据的方法 &#xff08;2&#xff09; 掌握更新操作与子查询结合的用法 2、实验预习与准备 &#xff08;1&#xff09; Update&#xff0c;Delete&am…

内网横向技术

如果拿下了一台机器之后寻找域控机器 ipconfig /all 找到域名 ping 域名或者nslookup域名

拼多多平台全面API接口对接

对接流程&#xff08;支持虚拟商品&#xff09; 拼多多与商家之间数据双向请求&#xff0c;同步更新及相关数据传输。对接主要分为三大部分&#xff1a;准备阶段、对接测试、上线使用&#xff1b;针对每部分具体说明如下&#xff1a; 接口连通性测试重点关注两类接口的连通性&a…

百度ai试用

JMaven Central: com.baidu.aip:java-sdk (sonatype.com) Java sdk地址如上&#xff1a; 文心一言开发者 文心一言 (baidu.com) ERNIE Bot SDK提供便捷易用的接口&#xff0c;可以调用文心一言的能力&#xff0c;包含文本创作、通用对话、语义向量、AI作图等。 pip install…

抖音电商品牌力不足咋办?如何升级或强开旗舰店、官方旗舰店?我们有妙招!

随着抖音电商的发展&#xff0c;越来越多的商家蜂拥而至&#xff0c;入驻经营抖音小店... 然而我们在开店的时候&#xff0c;选择开通官方旗舰店、旗舰店、专营店或专卖店&#xff0c;却被系统提示为你的商标品牌力不足&#xff0c;无法开通官方旗舰店、旗舰店、专营店、专卖店…

【AI考证笔记】NO.1人工智能的基础概念

以下部分内容来自于百度智能云人才认证培训讲义&#xff0c;腾讯等也有人工智能类似的讲义&#xff0c;限时免费&#xff0c;也就是不报考&#xff0c;也能系统学习&#xff0c;课程做的都是不错的。有感兴趣的朋友&#xff0c;可以去检索学习。 本系列是学习笔记&#xff0c;…

Android笔记(十四):JetPack Compose中附带效应(一)

在Android应用中可以通过定义可组合函数来搭建应用界面。应用界面的更新往往是与可组合函数内部定义的状态值相关联的。当界面的状态值发生变更&#xff0c;会导致应用界面进行更新。在Android笔记&#xff08;九&#xff09;&#xff1a;Compose组件的状态&#xff0c;对Compo…

定制嵌入式主板:满足客户的实际需求

随着物联网、智能家居、智能工厂等应用的不断发展&#xff0c;嵌入式系统的应用场景也越来越广泛。嵌入式系统的核心部分是嵌入式主板&#xff0c;而定制化的嵌入式主板已经成为了很多企业和项目的首选。本文将从以下几个方面介绍定制嵌入式主板。 一、定制嵌入式主板的概念 定…

华为云人工智能入门级开发者认证学习笔记

人工智能入门级开发者认证 人工智能定义 定义 人工智能 (Artificial Intelligence) 是研究、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。 强人工智能 vs 弱人工智能 强人工智能&#xff1a;强人工智能观点认为有可能制造出真正能推理&#xff08…

星河创新,开拓新纪!2023“星河产业应用创新奖”报名全面开启!

科技的浪潮汹涌而至&#xff0c;人工智能正悄无声息地渗透进我们生活的每一个角落&#xff0c;成为推动社会奔腾向前的强大引擎。 随着大模型时代到来&#xff0c;更多的创新者涌现出来&#xff0c;他们正积极探索AI与实体的深度融合&#xff0c;解决行业难题&#xff0c;开拓…

实时语音克隆:5 秒内生成任意文本的语音 | 开源日报 No.84

CorentinJ/Real-Time-Voice-Cloning Stars: 43.3k License: NOASSERTION 这个开源项目是一个实时语音克隆工具&#xff0c;可以在5秒内复制一种声音&#xff0c;并生成任意文本的语音。 该项目的主要功能包括&#xff1a; 从几秒钟的录音中创建声纹模型根据给定文本使用参考…

Talk | 牛津大学博士后研究员边佳旺:SC-DepthV3-动态场景中的自监督单目深度估计

本期为TechBeat人工智能社区第550期线上Talk。 北京时间11月23日(周四)20:00&#xff0c;牛津大学博士后研究员—边佳旺的Talk已准时在TechBeat人工智能社区开播&#xff01; 他与大家分享的主题是: “SC-DepthV3&#xff1a;动态场景中的自监督单目深度估计”&#xff0c;介绍…

前置微小信号放大器在生物医学中有哪些应用

前置微小信号放大器在生物医学领域中具有广泛的应用。生物医学信号通常具有较小的振幅和较低的幅频响应&#xff0c;因此需要借助放大器来增强信号以便进行准确的测量、监测和分析。以下是前置微小信号放大器在生物医学中的主要应用。 心电图&#xff08;ECG&#xff09;放大器…

window.requestAnimationFrame+localStorage+canvas实现跨窗口小球连线效果

文章目录 前言效果代码后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;前端系列文章 &#x1f431;‍&#x1f453;博主在前端领域还有很多知识和技术需要掌握&#xff0c;正在不断努力填补技术短板。(如果出现错误&#xff0c;感谢大家…

Golang并发模型:Goroutine 与 Channel 初探

文章目录 goroutinegoexit() channel缓冲closerangeselect goroutine goroutine 是 Go 语言中的一种轻量级线程&#xff08;lightweight thread&#xff09;&#xff0c;由 Go 运行时环境管理。与传统的线程相比&#xff0c;goroutine 的创建和销毁的开销很小&#xff0c;可以…

kali部署ARL灯塔资产系统及使用教程

网上有很多ARL部署到centos系统的教程,但是部署到ubuntu或kali linux系统的教程都是乱七八糟,互相抄,而且没有一个能部署成功,鉴于此,写下此教程,帮助大家出坑 一、安装docker环境(网上什么弄钥匙呀,什么稳定源啊都是垃圾) 准备一个纯净的最新的kali linux系统 1、配…