Netty:如何在 websocket 中使用查询字符串?

Posted

技术标签:

【中文标题】Netty:如何在 websocket 中使用查询字符串?【英文标题】:Netty: How to use query string with websocket? 【发布时间】:2016-08-11 11:44:10 【问题描述】:

这是我ChannelInitializer#initChannel的代码sn-ps

    ChannelPipeline p = ch.pipeline();

    p.addLast(new HttpServerCodec()         
    .addLast(new HttpObjectAggregator(65536))
    .addLast( new LoggingHandler(LogLevel.INFO))
    .addLast(new WebSocketServerProtocolHandler("/chat"))
    .addLast(new TextWebSocketFrameToChatMessageDecoder())
    .addLast(new UserAccessHandler())

可以通过ws://mydomain/chat接受,现在我想解析像ws://mydomain/chat?accesskey=hello这样的查询字符串

我查找了WebSocketServerProtocolHandler,但找不到如何获取查询字符串。

如何获取(或解析)查询字符串? 谢谢你的帮助。

【问题讨论】:

【参考方案1】:

重写方法:userEventTriggered 和处理事件 HandshakeComplete。

见WebSocketServerProtocolHandshakeHandler

Netty 4.1

public class TextWebSocketFrameToChatMessageDecoder extends SimpleChannelInboundHandler<WebSocketFrame> 
    public final static AttributeKey<Map<String,String>> RequestParams = AttributeKey.valueOf("request.params");

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception 
        if(evt instanceof HandshakeComplete)
            HandshakeComplete handshake = (HandshakeComplete)evt;

            //http request header
            HttpHeaders headers = handshake.requestHeaders();

            //http request uri: /chat?accesskey=hello
            String              uri    = handshake.requestUri(); 

            //TODO: parse uri parameters to map ...
            Map<String, String> params ;

            //put to channel context
            ctx.channel().attr(RequestParams).set(params);

        else
            ctx.fireUserEventTriggered(evt);
        
    

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) throws Exception 
        //on message
        if (frame instanceof TextWebSocketFrame) 
            Map<String, String> params    = ctx.channel().attr(RequestParams).get();
            String              accesskey = params.get("accesskey");
            System.out.println( accesskey ); //hello
         else 
            System.out.println( "Unsupported frame type: " + frame.getClass().getName() );
                
    

【讨论】:

【参考方案2】:

我创建了 3 个新类,复制它们。

WebSocketServerProtocolHandler WebSocketServerProtocolHandshakeHandler WebSocketProtocolHandler

在 WebSocketServerProtocolHandshakeHandler 的副本中,添加了这些代码

if(!req.getUri().matches(websocketPath))
    ctx.fireChannelRead(msg);
    return;


String [] splittedUri = req.getUri().split("\\?");
HashMap<String, String> params = new HashMap<String, String>();

if(splittedUri.length > 1)
    String queryString = splittedUri[1];
    for(String param : queryString.split("&"))
        String [] keyValue = param.split("=");
        if(keyValue != null && keyValue.length >= 2)
            logger.trace("key = , value = ", keyValue[0], keyValue[1]);
            params.put(keyValue[0], keyValue[1]);
        
    


ctx.channel().attr(AttrKeys.getInstance().params()).set(params);

现在我可以接受多个 uri 并很好地使用查询字符串。 我想有人会需要这个答案。

【讨论】:

我是 netty 的新手,面临同样的问题。你能分享一下你是如何获得URI参数的可行代码吗? @MahmoodSanjrani 太久以前了,所以我没有代码。我只是复制和编辑了那个处理程序。并改用那个处理程序。 好的没问题,能分享一下经验吗?

以上是关于Netty:如何在 websocket 中使用查询字符串?的主要内容,如果未能解决你的问题,请参考以下文章

netty系列之:使用netty搭建websocket服务器

Netty:如何限制每秒 websocket 通道消息?

netty系列之:使用netty搭建websocket客户端

netty系列之:使用netty搭建websocket客户端

如何使用 netty 运行 websocket 服务器而不处理其他类型的 HTTP 请求(如 GET 和 POST)。

在netty中使用websocket进行服务器推送[关闭]