netty+websocket模式下token身份验证遇到的问题

netty+websocket下pipeline中handler无法传递的问题

在ChannelPipeline中责任链的传递

ChannelPipeline pipeline = socketChannel.pipeline();

//websocket协议本身是基于http协议的,所以这边也要使用http解编码器
pipeline.addLast(new HttpServerCodec());
//以块的方式来写的处理器
pipeline.addLast(new ChunkedWriteHandler());
//netty是基于分段请求的,HttpObjectAggregator的作用是将请求分段再聚合,参数是聚合字节的最大长度
pipeline.addLast(new HttpObjectAggregator(8192));

//        pipeline.addLast(new ReadTimeoutHandler(60));

pipeline.addLast(httpRequestHandler);
//ws://server:port/context_path
//ws://localhost:9999/ws
//参数指的是contex_path
pipeline.addLast(new WebSocketServerProtocolHandler("/xdong",true));

//websocket定义了传递数据的6中frame类型
pipeline.addLast(xdongTextWebSocketFrameHandler);

在责任链中有两个我自定义的handler,分别是httpRequestHandler和xdongTextWebSocketFrameHandler,这两个handler的作用分别是处理http请求下的token身份验证和完成握手升级以及处理握手完成之后接收ws客户端传入的消息。

但是在我的代码过程中发生了问题,客户端能成功和服务器建立通道,但是却无法完成后续的消息传输,网上在线的ws测试客户端和我的服务端建立连接的时候也提示未收到服务端的握手包。

经过大佬的排查发现我在我的handler中并没有通过fire时间将消息给责任链中的下一个handler处理,实际上我虽然建立了通道但是却没有完成握手,更无法处理消息。

其中三个重要的handler在责任链中的顺序是这样的:

pipeline.addLast(httpRequestHandler);
//ws://server:port/context_path
//ws://localhost:9999/ws
//参数指的是contex_path
pipeline.addLast(new WebSocketServerProtocolHandler("/xdong",true));

//websocket定义了传递数据的6中frame类型
pipeline.addLast(xdongTextWebSocketFrameHandler);

httpRequestHandler这个handler放第一个的原因是第一次握手的时候,请求实际上还是个http请求, 我可以拿到url中的token完成身份验证的工作。但是完成了之后还需要调用下一个handler完成http到ws协议的升级。

WebSocketServerProtocolHandler这个handler是io.netty包中自带的handler用来完成http协议到websocket协议的升级, 并且明确提到消息处理的handler必须在该handler之后。
在这里插入图片描述
xdongTextWebSocketFrameHandler是一个消息处理的handler,在成功建立ws连接后用来接收客户端传输的消息。

在pipeLine中的加入顺序都是addLast, 所以都是有顺序的。在channelRead0方法中处理完当前的逻辑之后需要通过fire事件触发下一个InboundHandler。方法就是ctx.fireChannelRead(((FullHttpRequest) msg).retain())

 @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof FullHttpRequest) {
            handleHttpRequest(ctx, (FullHttpRequest) msg);
            ctx.fireChannelRead(((FullHttpRequest) msg).retain());
        } else if (msg instanceof WebSocketFrame) {
            ctx.fireChannelRead(((WebSocketFrame) msg).retain());
        }
    }
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值