2014-11-24 17 views
3

我想在一個應用程序(一種主要方法)中使用Netty(4.0.24)創建多個服務器(多個ServerBootstraps)。我看到了這個問題/答案,但它留下了許多未回答的問題: Netty 4.0 multi port with difference protocol each port 所以,這裏是我的問題: 上面的答案表明,我們需要做的是創建多個ServerBootstrap對象,並綁定()到每個。但大多數的代碼示例我看到一個ServerBootstrap會再調用是這樣的:如何在Netty中使用多個ServerBootstrap對象

try { 
    b.bind().sync().channel().closeFuture().sync(); 
} 
finally { 
    b.shutdown(); 
} 

因此不會在ServerBootstrap B抗粘連同步()調用的結果?那麼我們如何爲多個ServerBootstraps做到這一點?如果我們不調用sync(),會發生什麼?這組同步調用只能用b.shutdown()正常關閉服務器嗎?如果是這樣,有沒有辦法正常關閉多個ServerBootstraps?

另外,我不明白當我們調用bind()而不調用sync()時會發生什麼。服務器以某種方式繼續運行?我們如何優雅地關閉它?

很明顯,我很困惑這一切是如何工作的,可悲的是Netty文檔在這方面真的很缺乏。任何幫助將不勝感激。

回答

12

下面的例子,你引用和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())等待綁定完成(如果發生異常,則直接進入finally部分)。在這個階段,渠道已經準備就緒,並聆聽新的聯繫。
  • channel()命令獲取此監聽通道(父連接,但尚未連接)。所有客戶都將生成此父母的「孩子」頻道。
  • 在您處理程序中,在某些事件發生後,您決定關閉父通道(不是孩子,而是監聽並等待新套接字的人)。要完成此操作,請撥打parentChannel.close()(或通過子頻道child.parent().close())。
  • closeFuture()命令在這個關閉事件中獲得未來。
  • 當這個未來結束(完成)時,這是最後的sync()命令(closeFuture().sync())將發生。
  • 父通道關閉後,您可以要求正常關閉綁定通道。

所以這樣做(等待closeFuture然後shutdownGracefully)是關閉連接到此ServerBootstrap的所有資源的乾淨方法。

當然,你可以改變一些事情。例如,沒有先獲取頻道,而只是稍後想要在正常關機之前阻止。

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()命令後和前關閉ServerBootstraps等待。

+1

這是已知宇宙歷史上最令人敬畏的答案。謝謝! – Marc 2014-11-24 20:18:59

-4
public static void main(String[] args) { 
    new Thread(new Runnable(){ 
    @Override 
    public void run() { 
     //{...} ServerBootstrap 1 
    } 
    }).start(); 
    new Thread(new Runnable(){ 
    @Override 
    public void run() { 
     //{...} ServerBootstrap 2 
    } 
    }).start(); 
    new Thread(new Runnable(){ 
    @Override 
    public void run() { 
     //{...} ServerBootstrap 3 
    } 
    }).start(); 
} 
+0

這會產生不必要的附加線程... – 2014-12-27 20:01:43

相關問題