netty websocket:如何判断websocket频道何时打开?

netty websocket:如何判断websocket频道何时打开?,websocket,netty,Websocket,Netty,我正在编写一个netty/websocket服务器应用程序,其中对websocket客户端(例如浏览器)的写入来自另一个线程(即不是来自websocket) 这是netty 4.0.18.Final,我的应用程序主要基于提供的websocket服务器示例 我需要知道websocket通道何时打开,以便保存ChannelHandlerContext,以便其他线程可以执行写操作。我有一些有效的方法,但我希望有一种更可靠的方法 它看起来像WebSocketServerHandler。当浏览器连接到we

我正在编写一个netty/websocket服务器应用程序,其中对websocket客户端(例如浏览器)的写入来自另一个线程(即不是来自websocket)

这是netty 4.0.18.Final,我的应用程序主要基于提供的websocket服务器示例

我需要知道websocket通道何时打开,以便保存ChannelHandlerContext,以便其他线程可以执行写操作。我有一些有效的方法,但我希望有一种更可靠的方法

它看起来像WebSocketServerHandler。当浏览器连接到websocket时,channelRead0()会被调用两次。第二次调用的ChannelHandlerContext可用于将来对通道的写入

因此,我的方法是在第二次调用channelRead0()时采取一些措施。如果我在handleWebSocketFrame()中获得CloseWebSocketFrame,我将重置计数器

有更好的办法吗

更新:添加userEventTriggered()后,处理程序类如下所示:

公共类WebSocketServerHandler扩展了SimpleChannelInboundHandler{
...
@凌驾
public void channelRead0(ChannelHandlerContext ctx,Object msg)引发异常{
System.out.println(“read0”);
if(msg instanceof FullHttpRequest){
handleHttpRequest(ctx,(FullHttpRequest)msg);
}else if(msg instanceof WebSocketFrame){
扶手网架(ctx,(网架)msg);
}
}
@凌驾
public void userEventTriggered(ChannelHandlerContext ctx,Object evt)引发异常{
System.out.println(“用户事件”);
if(evt==WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE){
System.out.println(“打开通道”+ctx.toString());
...    
}否则{
超级用户事件触发(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));
   } 
}
公共类WebSocketServerInitializer扩展了ChannelInitializer{
...
@凌驾
public void initChannel(SocketChannel ch)引发异常{
ChannelPipeline=通道管道();
addLast(“codechttp”,新的HttpServerCodec());
pipeline.addLast(“聚合器”,新的HttpObjectAggregator(65536));
addLast(“handler”,新的WebSocketServerHandler(statusListener));
} 
}

您可以检查
服务器握手事件。握手完成
事件,如在my中完成,可用于:

@覆盖
public void userEventTriggered(ChannelHandlerContext ctx,Object evt)引发异常{
if(evt==WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE){
ctx.pipeline().remove(HttpRequestHandler.class);
group.writeAndFlush(新的TextWebSocketFrame(“客户端”+ctx.channel()+“连接”));
group.add(ctx.channel());
}否则{
超级用户事件触发(ctx、evt);
}
}

我添加了UserEventTrigger()(请参见上面的更新),但它从未被调用。当浏览器访问服务器时,channelRead0()会被调用两次。您能告诉我如何配置您的ChannelPipeline吗?我添加了管道配置。此外,我还意识到了为什么channelRead0()会被调用调用了两次:在演示中,浏览器以http启动。我也可以直接从javascript调用websocket url,然后在页面加载时只调用一次channelRead0()。
WebSocketServerProtocolHandler.ServerHandshakeStarteEvent.HANDSHAKE_COMPLETE
不推荐使用。
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));
   } 
}