我正在编写一个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));
}
}
答案 0 :(得分:0)
您可以检查我chat server example中完成的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);
}
}