netty 通过端口调用关闭

1 篇文章 0 订阅

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;
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值