步骤
- 构建一对主从线程组
- 定义服务器启动类
- 为服务设置Channel
- 设置处理从线程池的Handler初始化器
- 监听启动和关闭服务器
代码
入口类:HelloServer
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
public class HelloServer {
public static void main(String[] args) throws InterruptedException {
//定义一对线程组
//主线程组,用于接受客户端的连接,但是不做任何处理,跟老板一样,不做事
EventLoopGroup bossGroup = new NioEventLoopGroup();
//从线程组,老板线程组会把任务丢给他,让手下线程组做任务
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
//netty服务器创建,ServerBootstrap是一个启动类
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup,workerGroup)//设置主从线程组
.channel(NioServerSocketChannel.class)//设置nio的双向通道
.childHandler(new HelloServerInitlializer());//子处理器,用于处理workerGroup
//启动server,并且设置8888为启动的端口号,同时启动方式为同步
ChannelFuture channelFuture = serverBootstrap.bind(8888).sync();
//监听关闭的channel,设置位同步方式。
channelFuture.channel().closeFuture().sync();
}finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
初始化channel器
图解:channel的初始化器的作用。
代码
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpServerCodec;
/**
* 初始化器,channel注册后,会执行里面的对应的初始化方法。
*/
public class HelloServerInitlializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
//通过socketChannel获得对应的管道
ChannelPipeline pipeline = socketChannel.pipeline();
//通过管道,添加handler
// HttpServerCodec 当请求到服务端,我们需要做解码,响应到客户端需要做编码
pipeline.addLast("HttpServerCodec",new HttpServerCodec());
//添加的自定义handler
pipeline.addLast("myHandler",new MyHandler());
}
}
自定义Handler
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;
/**
* 自定义的handler
* SimpleChannelInboundHandler: 相当于队列入栈。
*/
public class MyHandler extends SimpleChannelInboundHandler<HttpObject> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
//获取channel
Channel channel = ctx.channel();
if (msg instanceof HttpRequest) {
//显示客户端远程地址
System.out.println(channel.remoteAddress());
//定义发送的数据消息
ByteBuf content = Unpooled.copiedBuffer("hello sb!", CharsetUtil.UTF_8);
//构建一个http response
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content);
//设置类型和长度
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain");
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes());
ctx.writeAndFlush(response);
}
}
@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
super.channelRegistered(ctx);
System.out.println("channel 注册。。。");
}
@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
super.channelUnregistered(ctx);
System.out.println("channel 移除。。。");
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
System.out.println("channel 激活。。。");
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
super.channelInactive(ctx);
System.out.println("channel 不活跃。。。");
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
super.channelReadComplete(ctx);
System.out.println("channel 读取完成。。。");
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
super.userEventTriggered(ctx, evt);
System.out.println("channel 用户事件触发。。。");
}
@Override
public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
super.channelWritabilityChanged(ctx);
System.out.println("channel 可写可更改。。。");
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
super.exceptionCaught(ctx, cause);
System.out.println("channel 捕获异常了。。。");
}
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
super.handlerAdded(ctx);
System.out.println("channel handler添加。。。");
}
@Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
super.handlerRemoved(ctx);
System.out.println("channel handler移除。。。");
}
}
网友评论