Netty:如何在 websocket 中使用查询字符串?
Netty: How to use query string with websocket?
这是我的 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
,但找不到如何获取查询字符串。
如何获取(或解析)查询字符串?
谢谢你的帮助。
我创建了 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 并很好地使用查询字符串。
我想有人会需要这个答案。
覆盖方法: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() );
}
}
}
这是我的 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
,但找不到如何获取查询字符串。
如何获取(或解析)查询字符串? 谢谢你的帮助。
我创建了 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 并很好地使用查询字符串。 我想有人会需要这个答案。
覆盖方法: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() );
}
}
}