我正在编写一个netty/websocket服务器应用程序,其中对websocket客户端(例如浏览器)的写入来自另一个线程(即不是来自websocket)。
这是netty 4.0.18.Final,我的应用程序主要基于提供的websocket服务器示例。
我需要知道websocket通道何时打开,这样我就可以保存ChannelHandlerContext,以便其他线程可以执行写入。我有一些有效的方法,但我希望有一个更稳健的方法。
当浏览器连接到websocket时,看起来WebSocketServerHandler.channelRead0()被调用了两次。第二个调用的ChannelHandlerContext可用于将来对通道的写入。
因此,我的方法是对channelRead0()的第二次调用执行一些操作。如果我在handleWebSocketFrame()中获得CloseWebSocketFrame,我会重置计数器。
有更好的方法吗?
更新:在添加userEventTriggered():之后,处理程序类看起来是这样的
public class WebSocketServerHandler extends SimpleChannelInboundHandler<Object> {
...
@Override
public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("read0");
if (msg instanceof FullHttpRequest) {
handleHttpRequest(ctx, (FullHttpRequest) msg);
} else if (msg instanceof WebSocketFrame) {
handleWebSocketFrame(ctx, (WebSocketFrame) msg);
}
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
System.out.println("userEvent");
if (evt == WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE) {
System.out.println("opening channel " + ctx.toString());
...
} else {
super.userEventTriggered(ctx, evt);
}
}
初始化器:
public class WebSocketServerInitializer extends ChannelInitializer<SocketChannel> {
...
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("codec-http", new HttpServerCodec());
pipeline.addLast("aggregator", new HttpObjectAggregator(65536));
pipeline.addLast("handler", new WebSocketServerHandler(statusListener));
}
}
您可以像我的聊天服务器示例中那样检查ServerHandshakeStateEvent.HANDSHAKE_COMPLETE
事件,它可以像一样使用
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt == WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE) {
ctx.pipeline().remove(HttpRequestHandler.class);
group.writeAndFlush(new TextWebSocketFrame("Client " + ctx.channel() + " joined"));
group.add(ctx.channel());
} else {
super.userEventTriggered(ctx, evt);
}
}