• Netty-Websocket 根据URL路由,分发机制的实现


    最近在做netty整合websocket,发现网上很多项目都是最简单的demo,单例的一个项目。

    然而公司的项目需要接受几个不同功能的ws协议消息,因此最好是用URL来区分,让页面上采用不同的链接方式。

    网上项目出现地址的方法:

    private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) {
            // 如果HTTP解码失败,返回HHTP异常
            if(!req.decoderResult().isSuccess() || (!"websocket".equals(req.headers().get("Upgrade")))) {
                
                sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST));
                
                return;
            }
            // 构造握手响应返回,本机测试
            WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory("ws://localhost:8088/websocket", null,
                    false);  //注意,这条地址别被误导了,其实这里填写什么都无所谓,WS协议消息的接收不受这里控制
            
            handshaker = wsFactory.newHandshaker(req);
            
            if(handshaker == null) {
                // WebSocketServerHandshakerFactory.sendUnsupportedWebSocketVersionResponse(ctx.channel());
                WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel());
                
            } else {
                handshaker.handshake(ctx.channel(), req);
            }
            
        }

    然后,开始看源码,发现ChannelHandlerContext继承的 AttributeMap

    然后继续看,AttributeMap有一个方法,attr(),返回Attribut,参数key。而Attrbute中有set()方法。

    好了,那么接下来一切都好办了,直接上关键代码。

    下面是netty接收到消息处理,第一步首先是http握手,这个没的说。

    /**
         * 接收客户端发送的消息 channel 通道 Read 读 简而言之就是从通道中读取数据,也就是服务端接收客户端发来的数据。但是这个数据在不进行解码时它是ByteBuf类型的
         */
        @Override
        protected void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
             // 传统的HTTP接入
            if (msg instanceof FullHttpRequest) {
                handleHttpRequest(ctx, ((FullHttpRequest) msg));
                // WebSocket接入
            } else if (msg instanceof WebSocketFrame) {
                if("anzhuo".equals(ctx.attr(AttributeKey.valueOf("type")).get())){
                handlerWebSocketFrame(ctx, (WebSocketFrame) msg);
                System.out.println(1111);
                }else{
                System.out.println(2323);
                handlerWebSocketFrame2(ctx, (WebSocketFrame) msg);
                }
            }
        }
        

    然后:

    private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) {
            // 如果HTTP解码失败,返回HHTP异常
            if (!req.getDecoderResult().isSuccess() || (!"websocket".equals(req.headers().get("Upgrade")))) {
                sendHttpResponse(ctx, req,
                        new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST));
                return;
            }
            
             HttpMethod method=req.getMethod();
             String uri=req.getUri();
            if(method==HttpMethod.GET&&"/webssss".equals(uri)){
                 //....处理    重点在这里,对于URL的不同,给ChannelHandlerContext设置一个Attribut
                ctx.attr(AttributeKey.valueOf("type")).set("anzhuo");
             }else if(method==HttpMethod.GET&&"/websocket".equals(uri)){
                 //...处理
                 ctx.attr(AttributeKey.valueOf("type")).set("live");
             }
    
              // 构造握手响应返回,本机测试
            WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
                    "ws://localhost:7397/websocket", null, false);
            handshaker = wsFactory.newHandshaker(req);
            if (handshaker == null) {
                WebSocketServerHandshakerFactory.sendUnsupportedWebSocketVersionResponse(ctx.channel());
            } else {
                handshaker.handshake(ctx.channel(), req);
            }
        }

    握手成功之后,发送消息时会返回第一段代码,因此判断context的Attribut就可以分发路由了,给不同的handlerWebSocketFrame处理机制

  • 相关阅读:
    Python 3学习 ——目录 Json Pickle
    Python 3 学习——函数扩展and迭代器生成器装饰器
    Python 3 学习——深浅拷贝以及函数
    Python 3 学习的第七小节——Linux-Ubuntu
    Python 3 —— 文件操作
    Python 3 学习的第五小节——字符编码与三级菜单实践
    关于PHP代码复用‘traits’的一段代码
    一个将对象彻底冻结的函数
    详解vue-cli脚手架项目-package.json
    关于element-ui日期选择器disabledDate使用心得
  • 原文地址:https://www.cnblogs.com/tohxyblog/p/7771200.html
Copyright © 2020-2023  润新知