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

时间:2016-08-11 11:44:11

标签: java websocket netty

以下是我ChannelInitializer#initChannel

的代码段
    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,但我找不到如何获取查询字符串。

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

2 个答案:

答案 0 :(得分: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() );
        }        
    }
}

答案 1 :(得分:0)

我创建了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并很好地使用查询字符串。 我想有人会需要这个答案。