Netty - 频道立即关闭

时间:2013-08-29 14:37:06

标签: java netty

我开始使用netty并且(显然)想要在客户端和服务器之间发送消息。由于我处于早期阶段,我遇到了简单的问题,在这种情况下,它正在发送消息。这就是我创建服务器和客户端的方式:

客户端:

public void run() throws Exception
{
    EventLoopGroup group = new NioEventLoopGroup();
    try
    {
        Bootstrap b = new Bootstrap();
        b.group(group)
                .channel(NioSocketChannel.class)
                .handler(new SecureChatClientInitializer());
        b.option(ChannelOption.SO_KEEPALIVE, true);

        // Start the connection attempt.
        ChannelFuture future = b.connect(new InetSocketAddress(host, port));
        Channel ch = future.awaitUninterruptibly().channel();
        ch.writeAndFlush("hi\r\n");

        // Wait until all messages are flushed before closing the channel.
        if (lastWriteFuture != null)
        {
            lastWriteFuture.sync();
        }
    } finally
    {
        // The connection is closed automatically on shutdown.
        group.shutdownGracefully();
    }
}

服务器:

public void run() throws InterruptedException
{
    EventLoopGroup bossGroup = new NioEventLoopGroup();
    EventLoopGroup workerGroup = new NioEventLoopGroup();
    try
    {
        ServerBootstrap b = new ServerBootstrap();
        b.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new SecureChatServerInitializer(sessionManager));
        b.option(ChannelOption.SO_KEEPALIVE, true);
        b.bind(port).sync().channel().closeFuture().sync();

    } finally
    {
        bossGroup.shutdownGracefully();
        workerGroup.shutdownGracefully();
    }
}

客户端初始化程序:

public class SecureChatClientInitializer extends ChannelInitializer<SocketChannel>
{

    @Override
    public void initChannel(SocketChannel ch) throws Exception
    {
           ChannelPipeline pipeline = ch.pipeline();

        SSLEngine engine =
                SecureChatSslContextFactory.getClientContext().createSSLEngine();
        engine.setUseClientMode(true);
        pipeline.addLast("ssl", new SslHandler(engine));
        pipeline.addLast("framer", new DelimiterBasedFrameDecoder(
                8192, Delimiters.lineDelimiter()));
        pipeline.addLast("decoder", new StringDecoder());
        pipeline.addLast("encoder", new StringEncoder());
        pipeline.addLast("handler", new SecureChatClientHandler());
    }
}

服务器初始化程序:

public class SecureChatServerInitializer extends ChannelInitializer<SocketChannel>
{

    ...

    @Override
    public void initChannel(SocketChannel ch) throws Exception
    {
        ChannelPipeline pipeline = ch.pipeline();

        SSLEngine engine =
                SecureChatSslContextFactory.getServerContext().createSSLEngine();
        engine.setUseClientMode(false);
        pipeline.addLast("ssl", new SslHandler(engine));
        pipeline.addLast("framer", new DelimiterBasedFrameDecoder(
                8192, Delimiters.lineDelimiter()));
        pipeline.addLast("decoder", new StringDecoder());
        pipeline.addLast("encoder", new StringEncoder());
        pipeline.addLast("handler", new SecureChatServerHandler(sessionManager));
    }
}

您可能已经从猜测源代码中猜到了:是的,部分内容来自SecureChatExample。我编辑了部分内容并且不明白为什么它不再起作用。执行客户端时,我只收到一行错误消息:

java.nio.channels.ClosedChannelException

2 个答案:

答案 0 :(得分:0)

只有在您确实要退出客户端时才调用group.shutdownGracefully();。如果您从客户端删除该行,Channel将保持打开状态。

此外,您只需要在发送的所有邮件的末尾添加\n后缀。

答案 1 :(得分:0)

除此之外,你可以这样关闭频道:

  @Override
  public void channelActive(ChannelHandlerContext ctx) {
    ctx.channel().pipeline().remove(this);
  }