Netty WebSocket URI参数传递问题,一文搞定

849 阅读2分钟

起因


  在做websocket连接时验证当前用户是否需要接收异常数据提醒的功能的时候,发现传了个参数,但是后台接收不到这个参数,就开始研究怎么才能传递参数。

方法1


  直接把参数放到url后面 (new WebSocket("ws://127.0.0.1:12345/ws/?id=value"))然后自己解析参数

@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
    System.out.println("触发事件");
    if (evt instanceof WebSocketServerProtocolHandler.HandshakeComplete) {
        WebSocketServerProtocolHandler.HandshakeComplete complete = (WebSocketServerProtocolHandler.HandshakeComplete) evt;
        String uri = complete.requestUri();
        System.out.println("uri: " + uri);
        //输出带参数的uri , 然后截取参数
        if (null != uri && uri.contains("/ws") && uri.contains("?")) {
            String[] uriArray = uri.split("\?");
            if (null != uriArray && uriArray.length > 1) {
                String[] paramsArray = uriArray[1].split("=");
                if (null != paramsArray && paramsArray.length > 1) {
                    // 
                    String param= paramsArray[1];
                }
                System.out.println("握手成功");
            }
        }
    }

}

  上面的方法加了参数之后没有触发userEventTriggered,不知道咋回事,没解决。

后面看源码 发现 channelRead里边的msg有这个uri参数,就用这个方法去处理参数。

image.png

image.png

  一开始像下面这么写的以为能直接用,结果报错了

// String uri =  ((DefaultHttpRequest) ((HttpObjectAggregator.AggregatedFullHttpRequest) msg).message).uri();

  再看看源码,发现这是在Netty框架内部的实现细节,是私有的,不能直接访问。就去找它的实现类,发现它是实现的FullHttpRequest,这个是Netty提供的公共方法,可以被调用到,于是就用这个。

image.png

最后实现方式代码如下:

@Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println(msg);
        String uri = ((FullHttpRequest) msg).uri();
         // String uri =  ((DefaultHttpRequest) ((HttpObjectAggregator.AggregatedFullHttpRequest) msg).message).uri();
        System.out.println("uri: " + uri);
        //输出带参数的uri , 然后截取出来需要的参数
        if (null != uri && uri.contains("/ws") && uri.contains("?")) {
            String[] uriArray = uri.split("\\?");
            if (null != uriArray && uriArray.length > 1) {
                String[] paramsArray = uriArray[1].split("=");
                if (null != paramsArray && paramsArray.length > 1) {
                    // 参数获取
                    String param= paramsArray[1];
                }
                System.out.println("握手成功");
            }
        }
    }

方法2


  在客户端设置连接成功回调 ,连接成功发送参数。

var socket = new WebSocket("ws://127.0.0.1:12345/ws"); 

// 发送参数
socket.onopen = function (event) {
	socket1.send("value")
}

@Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, TextWebSocketFrame textWebSocketFrame) throws Exception {
        // 传的参数
        String text = textWebSocketFrame.text();
        
        // ... 拿到参数之后怎么处理的具体逻辑省略
    }

pom


<!--netty-->
     <dependency>
         <groupId>io.netty</groupId>
         <artifactId>netty-all</artifactId>
     </dependency>
     ```