netty 通过端口调用关闭

package websocketdemo.timeserver2;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
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.codec.http.HttpServerCodec;

/**
 * 通过端口调用关闭netty演示<br />
 * 调用方法<br />
 * new TimeServer(8080, 8081).run(); //8080, 正常工作商品, 8081, 关闭端口<br />
 * http;//127.0.0.1:8081/close; //关闭netty
 * @author lizw
 */
public class TimeServer {

	private int port;
	private int port_shutdown;

	public TimeServer(int port) {
		this.port = port;
	}
	public TimeServer(int port, int port_shutdown) {
		this.port = port;
		this.port_shutdown = port_shutdown;
	}

	public void run() throws Exception {
		//用于常规端口的Group
		EventLoopGroup bossGroup = new NioEventLoopGroup();
		EventLoopGroup workerGroup = new NioEventLoopGroup();
		//用于关闭端口的Group
		EventLoopGroup bossGroup2 = new NioEventLoopGroup();
		EventLoopGroup workerGroup2 = new NioEventLoopGroup();
		try {
			ServerBootstrap b=null;		//常规netty服务
			ServerBootstrap b2=null;	//关闭netty服务
			ChannelFuture f=null;
			ChannelFuture f2=null;
			{
				//常规端口服务器建立
				System.out.println("start regular netty server thread");
				b = new ServerBootstrap(); // (2)
				b.group(bossGroup, workerGroup)
						.channel(NioServerSocketChannel.class) // (3)
						.childHandler(new ChannelInitializer<SocketChannel>() { // (4)
							@Override
							public void initChannel(SocketChannel ch) throws Exception {
								ch.pipeline().addLast(new TimeServerHandler());
							}
						})
						.option(ChannelOption.SO_BACKLOG, 128) // (5)
						.childOption(ChannelOption.SO_KEEPALIVE, true); // (6)

				// Bind and start to accept incoming connections.
				f = b.bind(port).sync(); // (7)
			}
			{
				//关闭netty应用服务器建立
				System.out.println("start shutdown netty server thread");
				b2 = new ServerBootstrap();
				b2.group(workerGroup2, bossGroup2);
				b2.channel(NioServerSocketChannel.class);
				final EventLoopGroup[] group={workerGroup, bossGroup, workerGroup2, bossGroup2};
				b2.childHandler(new ChannelInitializer() {

					@Override
					protected void initChannel(Channel ch) throws Exception {
						ch.pipeline().addLast(new HttpServerCodec());
						ch.pipeline().addLast(new CloaseServerHandler(group));
					}
				});
				f2 = b2.bind(port_shutdown).sync();
			}
			
			f.channel().closeFuture();
			f2.channel().closeFuture();
			System.out.println("netty服务器运行中");
		} finally {
		}
		
	}

	public static void main(String[] args) throws Exception {
		System.out.println("main start");
		int port=8080;
		int port_shutdown=8081;
		new TimeServer(port, port_shutdown).run();
		System.out.println("main end");
	}
}



/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package websocketdemo.timeserver2;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.EventLoopGroup;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.DefaultHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import static io.netty.handler.codec.http.HttpHeaders.Names.ACCEPT_RANGES;
import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_LENGTH;
import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE;
import static io.netty.handler.codec.http.HttpHeaders.Names.DATE;
import static io.netty.handler.codec.http.HttpHeaders.Names.SERVER;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion;
import java.io.UnsupportedEncodingException;
import java.util.Date;

/**
 * 处理http请求, 用于判断 uri = "/close" 时关闭netty应用
 * @author lizw
 */
public class CloaseServerHandler extends ChannelInboundHandlerAdapter {

	EventLoopGroup[] group;

	public CloaseServerHandler(EventLoopGroup[] group) {
		this.group = group;
	}


	/**
	 * 处理http请求, 如果 uri = "/close" 则关闭服务器, 否则返回 404页面(BAD_GATEWAY)
	 * @param ctx
	 * @param msg
	 * @throws Exception 
	 */
	@Override
	public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception {
		super.channelActive(ctx); //To change body of generated methods, choose Tools | Templates.
		DefaultHttpRequest req=null;
		FullHttpResponse response=null;
		boolean isClose=false;
		if(msg instanceof DefaultHttpRequest){
			req=(DefaultHttpRequest)msg;
			String uri=req.getUri();
			if(0==uri.indexOf("/close"))
				isClose=true;
		}
		response=closeNetty(isClose);
		final ChannelFuture cf = ctx.writeAndFlush(response); // (3)
		if(!isClose)
			return;
		cf.addListener(new ChannelFutureListener() {
			@Override
			public void operationComplete(ChannelFuture future) {
				ctx.close();
				System.out.println("服务器马上关闭");
				for (EventLoopGroup g : group) {
					g.shutdownGracefully();
				}
				System.out.println("服务器马上完成");
			}
		});
	}

	/**
	 * 关闭netty请求的响应
	 * @param flag true - 关闭, false - 返回 404页面(BAD_GATEWAY)
	 * @param FullHttpResponse
	 */
	private FullHttpResponse closeNetty(boolean flag) throws UnsupportedEncodingException{
		FullHttpResponse response=null;
		if(flag){
			String text=new String("服务器即将关闭");
			ByteBuf buf = Unpooled.wrappedBuffer(text.getBytes("utf-8"));
			response=new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, buf);
		}else{
			String text=new String("404");
			ByteBuf buf = Unpooled.wrappedBuffer(text.getBytes("utf-8"));
			response=new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_GATEWAY, buf);
		}
		response.headers().set(CONTENT_TYPE, "text/html;charset=utf-8");
		response.headers().set(CONTENT_LENGTH, response.content().readableBytes());
		response.headers().set(DATE, new Date().toString());
		response.headers().set(SERVER, "netty-4.0.29-Final");
		response.headers().set(ACCEPT_RANGES, "bytes");
		return response;
	}
}

你可能感兴趣的:(netty 通过端口调用关闭)