当前位置: 首页 > 知识库问答 >
问题:

如何在Netty中使用多个ServerBootstrap对象

傅阿苏
2023-03-14
try {
    b.bind().sync().channel().closeFuture().sync();
}
finally {
    b.shutdown();
}

另外,我不明白当我们只调用bind()而不调用sync()时会发生什么。服务器是否以某种方式继续运行?我们如何优雅地关闭它?

很明显,我对这一切的工作原理感到非常困惑,可悲的是,在这方面缺乏完整的文档。任何帮助都将不胜感激。

共有1个答案

邓元白
2023-03-14

下面是您引用的示例,并添加了关于sync()方法的问题,下面是一个示例代码:

EventLoopGroup bossGroup = new NioEventLoopGroup(numBossThreads);
EventLoopGroup workerGroup = new NioEventLoopGroup(numWorkerThreads);
ServerBootstrap sb1 = null;
ServerBootstrap sb2 = null;
ServerBootstrap sb3 = null;
Channel ch1 = null;
Channel ch2 = null;
Channel ch3 = null;
try {
    sb1 = new ServerBootstrap();
    sb1.group(bossGroup, workerGroup);
    ...
    ch1 = sb1.bind().sync().channel();

    sb2 = new ServerBootstrap();
    sb2.group(bossGroup, workerGroup);
    ...
    ch2 = sb2.bind().sync().channel();

    sb3 = new ServerBootstrap();
    sb3.group(bossGroup, workerGroup);
    ...
    ch3 = sb3.bind().sync().channel();
} finally {
    // Now waiting for the parent channels (the binded ones) to be closed
    if (ch1 != null) {
        ch1.closeFuture().sync();
    }
    if (b1 != null) {
        b1.shutdownGracefully();
    }
    if (ch2 != null) {
        ch2.closeFuture().sync();
    }
    if (b2 != null) {
        b2.shutdownGracefully();
    }
    if (ch3 != null) {
        ch3.closeFuture().sync();
    }
    if (b3 != null) {
        b3.shutdownGracefully();
    }

所以现在解释一下(我试着):

  • bind()命令创建侦听相应的套接字。它立即返回(不阻塞),因此父通道可能尚未可用。
  • 第一个sync()命令(bind().sync())等待绑定完成(如果引发异常,则直接转到最后部分)。在此阶段,通道已准备就绪,并且肯定会侦听新的连接。
  • channel()命令获取这个侦听通道(父通道,尚未连接到任何人)。所有客户端都将生成此父信道的“子”信道。
  • 在处理程序中,在某个事件之后,您决定关闭父通道(不是子通道,而是正在监听和等待新套接字的通道)。要完成此关闭,只需调用parentchannel.close()(或从子通道child.parent().close()).
  • closefuture()命令将获取此关闭事件的未来值。
  • 当这个未来结束(完成)时,将执行最后一个sync()命令(closefuture().sync())。
  • 父通道关闭后,您可以请求正常关闭绑定通道。

当然,你可以改变一些东西。例如,不是首先获取通道,而是在您想要在优雅地关闭之前阻止时才获取通道。

EventLoopGroup bossGroup = new NioEventLoopGroup(numBossThreads);
EventLoopGroup workerGroup = new NioEventLoopGroup(numWorkerThreads);
ServerBootstrap sb1 = null;
ServerBootstrap sb2 = null;
ServerBootstrap sb3 = null;
ChannelFuture cf1 = null;
ChannelFuture cf2 = null;
ChannelFuture cf3 = null;
try {
    sb1 = new ServerBootstrap();
    sb1.group(bossGroup, workerGroup);
    ...
    cf1 = sb1.bind();

    sb2 = new ServerBootstrap();
    sb2.group(bossGroup, workerGroup);
    ...
    cf2 = sb2.bind();

    sb3 = new ServerBootstrap();
    sb3.group(bossGroup, workerGroup);
    ...
    cf3 = sb3.bind();
} finally {
    // Now waiting for the parent channels (the binded ones) to be closed
    if (cf1 != null) {
        cf1.sync().channel().closeFuture().sync();
    }
    if (cf2 != null) {
        c2.sync().channel().closeFuture().sync();
    }
    if (cf3 != null) {
        cf3.sync().channel().closeFuture().sync();
    }
    if (b1 != null) {
        b1.shutdownGracefully();
    }
    if (b2 != null) {
        b2.shutdownGracefully();
    }
    if (b3 != null) {
        b3.shutdownGracefully();
    }

这样你就不会在打开所有3个频道时阻塞,但在关闭它们之前等待所有3个频道都完成。

最后,如果在bind()事件上不阻塞,那么在closefuture()事件上不阻塞,则由您定义在sbx.bind()命令之后和关闭服务器引导程序之前如何等待。

 类似资料:
  • Norman Maurer有一个小的Netty最佳实践指南,建议尽可能重复使用NioEventLoopGroup,更准确地说,该指南指出 如果可以,请重用EventLoopGroup! 在我的情况下,我写了一个应用程序,将金融价格变动数据多路复用到一堆连接的Web套接字客户端。目前有三个引导程序,目前它们都使用单独的蔚来环集团: 1个ServerBootStrap处理连接的Web套接字。 1个Bo

  • 我试图在OpenGL中使用多个VAO和VBO渲染多个对象。使用相同的顶点渲染多个对象我已经做过了,但是我想做的是为每个对象使用不同的顶点,例如画一个正方形和一个圆形。对于一个正方形,我只需要6个顶点,但是对于圆,我需要360个顶点。我有阅读或创建着色器的错误。 以下是顶点着色器: 片段着色器: VAO和VBO的生成与绑定 以及渲染循环中的绘制调用: 我重复一遍,用我做过的相同顶点绘制多个对象。我需

  • 我将创建一个身份验证服务器,它本身与一组不同的Oauth2.0服务器交互。Netty似乎是在这里实现网络部分的一个很好的候选者。但在开始之前,我需要澄清一些关于netty的细节,因为我是新手。例行程序如下: > < li> 服务器接受来自客户端的HTTPS连接。 然后,不关闭第一个连接,它通过HTTPS与远程OAuth2.0服务器建立另一个连接并获取数据 毕竟,服务器将结果发送回客户端,客户端应该

  • 如果我向Drools引擎添加一个事实,我有一组正确工作的Drools规则,如果我添加两个事实,这些规则只应用于第一个事实。如何使规则集适用于多个事实? 我的可追踪事实: 我的规则集: 失败的测试用例:

  • 问题内容: 我想通过使用Laravel Eloquent中的方法对Laravel 4中的多列进行排序。查询将使用Eloquent生成,如下所示: 我怎样才能做到这一点? 问题答案: 只需根据需要调用多次。例如: 产生以下查询:

  • 问题内容: 我有SQL Server 2000, 它不支持MultipleActiveResults 。 我必须进行多次插入,并且每次插入都要进行一次连接。 我想在所有插入之前开始一个事务,并在所有插入之后完成它。 我该怎么做? 问题答案: 您不使用一个连接和多个命令(实际上是在循环中重新创建一个命令)的原因是什么?也许此解决方案将为您工作: 另请参见 Sql Server事务-ADO.NET 2