Netty提供了很好的WebSocket支持,可以通过添加WebSocketServerProtocolHandler实现暴露一个WebSocket接口。但是,如果需要在WebSocket的URI中添加参数queryString,例如/im/ws?w=221100234&t=99,则连接可能无法建立,浏览器会报错“Connection closed before receiving a handshake response” .
WebSocket协议是基于HTTP协议的,因此可以使用HTTP的参数传递方式来传递WebSocket参数。下面是一些可行的方法:
将参数添加到URI中。可以通过将参数添加到WebSocket URI中来传递参数。例如,如果需要将参数w=221100234&t=99传递给WebSocket服务器,则可以将WebSocket URI设置为ws://localhost:8000/im/ws?w=221100234&t=99。这种方法可以通过WebSocketServerProtocolHandler轻松实现,但是可能会导致连接无法建立 .
将参数添加到HTTP头中。除了将参数添加到URI中,还可以将参数添加到HTTP头中。可以使用WebSocketClientHandshaker类的handshake()方法来指定HTTP头。例如:
WebSocketClientHandshaker handshaker = WebSocketClientHandshakerFactory.newHandshaker(uri, WebSocketVersion.V13, null, true, headers);
ChannelFuture future = bootstrap.connect(uri.getHost(), uri.getPort());
future.syncUninterruptibly();
WebSocketClientHandler handler = (WebSocketClientHandler) future.channel().pipeline().last();
handshaker.handshake(future.channel());
handler.handshakeFuture().syncUninterruptibly();
在上面的示例中,headers是一个DefaultHttpHeaders对象,其中包含要添加到HTTP头中的参数。这种方法可以通过WebSocketClientProtocolHandler轻松实现
将参数添加到WebSocket握手处理程序中。还可以将参数添加到WebSocket握手处理程序中。可以使用WebSocketServerProtocolHandler类的handshake()方法来指定WebSocket握手处理程序。例如
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new HttpServerCodec());
pipeline.addLast(new HttpObjectAggregator(65536));
pipeline.addLast(new WebSocketServerCompressionHandler());
pipeline.addLast(new WebSocketServerProtocolHandler("/im/ws", null, true, 65536, true) {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof FullHttpRequest) {
FullHttpRequest req = (FullHttpRequest) msg;
String queryString = req.uri().split("\\?")[1];
QueryStringDecoder queryStringDecoder = new QueryStringDecoder(queryString, Charset.forName("UTF-8"));
String w = queryStringDecoder.parameters().get("w").get(0);
String t = queryStringDecoder.parameters().get("t").get(0);
// TODO: handle w and t parameters
} else {
super.channelRead(ctx, msg);
}
}
});
pipeline.addLast(new MyWebSocketServerHandler());
在上面的示例中,/im/ws是WebSocket URI的路径,WebSocketServerProtocolHandler的第二个参数为null表示不使用子协议,true表示WebSocket握手处理程序应该负责关闭空闲连接,65536表示WebSocket消息的最大大小,true表示WebSocket握手处理程序应该处理CloseWebSocketFrame .
在实现WebSocket参数传递时,需要注意以下几点:
确保WebSocket URI的格式正确。在将参数添加到WebSocket URI中时,需要确保URI的格式正确。例如,URI应该以ws://或wss://开头,端口号应该在URI中指定。
确保参数名称和值都经过正确的编码。在将参数添加到URI或HTTP头中时,需要确保参数名称和值都经过正确的编码。可以使用URLEncoder类将参数编码为URL编码格式。
确保WebSocket握手处理程序正确处理参数。在将参数添加到WebSocket握手处理程序中时,需要确保处理程序正确地解析和处理参数。可以使用QueryStringDecoder类解码URI中的查询字符串。