2015-01-19 6 views
12

मैं नेटटी 4.0.24 का उपयोग कर रहा हूं। फाइनल।शट डाउन नेटटी प्रोग्रामेटिक

मुझे नेटटी सर्वर प्रोग्रामेटिक रूप से प्रारंभ/बंद करने की आवश्यकता है।
सर्वर शुरू करने पर, धागा

f.channel().closeFuture().sync()

पर अवरुद्ध हो जाता है कृपया कुछ संकेत के साथ मदद उसे सही ढंग से करने के लिए। नीचे इकोसेवर है जिसे मुख्य श्रेणी द्वारा बुलाया जाता है। धन्यवाद।

package nettytests; 

import io.netty.bootstrap.ServerBootstrap; 
import io.netty.channel.ChannelFuture; 
import io.netty.channel.ChannelInitializer; 
import io.netty.channel.ChannelOption; 
import io.netty.channel.EventLoopGroup; 
import io.netty.channel.nio.NioEventLoopGroup; 
import io.netty.channel.socket.SocketChannel; 
import io.netty.channel.socket.nio.NioServerSocketChannel; 
import io.netty.handler.logging.LogLevel; 
import io.netty.handler.logging.LoggingHandler; 

public class EchoServer { 

    private final int PORT = 8007; 
    private EventLoopGroup bossGroup; 
    private EventLoopGroup workerGroup; 

    public void start() throws Exception { 
     // Configure the server. 
     bossGroup = new NioEventLoopGroup(1); 
     workerGroup = new NioEventLoopGroup(1); 
     try { 
      ServerBootstrap b = new ServerBootstrap(); 
      b.group(bossGroup, workerGroup) 
      .channel(NioServerSocketChannel.class) 
      .option(ChannelOption.SO_BACKLOG, 100) 
      .handler(new LoggingHandler(LogLevel.INFO)) 
      .childHandler(new ChannelInitializer<SocketChannel>() { 
       @Override 
       public void initChannel(SocketChannel ch) throws Exception { 
        ch.pipeline().addLast(new EchoServerHandler()); 
       } 
      }); 

      // Start the server. 
      ChannelFuture f = b.bind(PORT).sync(); 

      // Wait until the server socket is closed. Thread gets blocked. 
      f.channel().closeFuture().sync(); 
     } finally { 
      // Shut down all event loops to terminate all threads. 
      bossGroup.shutdownGracefully(); 
      workerGroup.shutdownGracefully(); 
     } 
    } 

    public void stop(){ 
     bossGroup.shutdownGracefully(); 
     workerGroup.shutdownGracefully(); 
    } 
} 


package nettytests; 

public class Main { 
    public static void main(String[] args) throws Exception { 
     EchoServer server = new EchoServer(); 
     // start server 
     server.start(); 

     // not called, because the thread is blocked above 
     server.stop(); 
    } 
} 

अद्यतन: मैं निम्नलिखित तरीके से EchoServer वर्ग बदल दिया है। विचार एक नए धागे में सर्वर शुरू करना और EventLoopGroups के लिंक को संरक्षित करना है। क्या यह सही तरीका है? निम्नलिखित

// once having an event in your handler (EchoServerHandler) 
// Close the current channel 
ctx.channel().close(); 
// Then close the parent channel (the one attached to the bind) 
ctx.channel().parent().close(); 

खत्म हो जाएगा इस तरह से कर रहा:

// Wait until the server socket is closed. Thread gets blocked. 
f.channel().closeFuture().sync(); 

मुख्य भाग पर एक अतिरिक्त थ्रेड के लिए कोई ज़रूरत नहीं

package nettytests; 

import io.netty.bootstrap.ServerBootstrap; 
import io.netty.channel.ChannelFuture; 
import io.netty.channel.ChannelInitializer; 
import io.netty.channel.ChannelOption; 
import io.netty.channel.EventLoopGroup; 
import io.netty.channel.nio.NioEventLoopGroup; 
import io.netty.channel.socket.SocketChannel; 
import io.netty.channel.socket.nio.NioServerSocketChannel; 
import io.netty.handler.logging.LogLevel; 
import io.netty.handler.logging.LoggingHandler; 

/** 
* Echoes back any received data from a client. 
*/ 
public class EchoServer { 

    private final int PORT = 8007; 
    private EventLoopGroup bossGroup; 
    private EventLoopGroup workerGroup; 

    public void start() throws Exception { 
     new Thread(() -> { 
      // Configure the server. 
      bossGroup = new NioEventLoopGroup(1); 
      workerGroup = new NioEventLoopGroup(1); 
      Thread.currentThread().setName("ServerThread"); 
      try { 
       ServerBootstrap b = new ServerBootstrap(); 
       b.group(bossGroup, workerGroup) 
         .channel(NioServerSocketChannel.class) 
         .option(ChannelOption.SO_BACKLOG, 100) 
         .handler(new LoggingHandler(LogLevel.INFO)) 
         .childHandler(new ChannelInitializer<SocketChannel>() { 
          @Override 
          public void initChannel(SocketChannel ch) throws Exception { 
           ch.pipeline().addLast(new EchoServerHandler()); 
          } 
         }); 

       // Start the server. 
       ChannelFuture f = b.bind(PORT).sync(); 

       // Wait until the server socket is closed. 
       f.channel().closeFuture().sync(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } finally { 
       // Shut down all event loops to terminate all threads. 
       bossGroup.shutdownGracefully(); 
       workerGroup.shutdownGracefully(); 
      } 
     }).start(); 
    } 

    public void stop() throws InterruptedException { 
     workerGroup.shutdownGracefully(); 
     bossGroup.shutdownGracefully(); 
    } 
} 

उत्तर

9

एक तरह से की तरह कुछ बनाने के लिए है। अब सवाल यह है कि किस तरह की घटना? यह आप पर निर्भर है ... इको हैंडलर में "शटडाउन" के रूप में एक संदेश हो सकता है जिसे शट डाउन के आदेश के रूप में लिया जाएगा और न केवल "छोड़ें" जो केवल क्लाइंट चैनल को बंद करने के रूप में बदल जाएगा। कुछ और हो सकता है ...

यदि आप किसी बच्चे के चैनल से शट डाउन नहीं करते हैं (इसलिए अपने हैंडलर के माध्यम से) लेकिन किसी अन्य प्रक्रिया के माध्यम से (उदाहरण के लिए मौजूदा स्टॉप फ़ाइल की तलाश में), तो आपको एक अतिरिक्त थ्रेड चाहिए इस घटना की प्रतीक्षा करेंगे और फिर सीधे channel.close() बनाएं जहां चैनल माता-पिता (f.channel() से) उदाहरण के लिए ...

कई अन्य समाधान मौजूद हैं।

संबंधित मुद्दे