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

时间:2014-04-15 21:12:49

标签: websocket netty

我正在编写一个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));
   } 
}

1 个答案:

答案 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);
    }
}