Maven依赖
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.25.Final</version>
</dependency>
HelloServer
package com.mqtt.netty;
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 HelloServerInitilializer()); // 子处理器,针对从线程组所做的操作
// http://127.0.0.1:8888
ChannelFuture channelFuture = serverBootstrap.bind(8888).sync() ;
// 监听关闭的channel
channelFuture.channel().closeFuture().sync();
}finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
初始化器
package com.mqtt.netty;
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 HelloServerInitilializer extends ChannelInitializer<SocketChannel>{
@Override
protected void initChannel(SocketChannel channel) throws Exception {
// 通过SocketChannel去获得对应的管道
ChannelPipeline pipeline = channel.pipeline();
//pipeline.addLast("logging",new LoggingHandler("DEBUG"));
// 当请求到服务器端,需要做解码,响应到客户端做编码
pipeline.addLast("HttpServerCodec", new HttpServerCodec());
// 添加自定义的助手类,返回字符串
pipeline.addLast("customHandler", new CustomHandler());
}
}
自定义助手类
package com.mqtt.netty;
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.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpObject;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.util.CharsetUtil;
/**
* 创建自定义助手类
*
* */
public class CustomHandler 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 netty ", CharsetUtil.UTF_8);
// 构建一个 http resposne
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);
}
}
}
在浏览器访问 http://127.0.0.1:8888/ 查看效果。
关于作者
王硕,网名信平,十多年软件开发经验,业余架构师,精通Java/Python/Go等,喜欢研究技术,著有《PyQt 5 快速开发与实战》《Python 3.* 全栈开发》,多个业余开源项目托管在GitHub上,欢迎微博交流。