本文将介绍 Netty 网络框架入门的相关内容,包括其基本概念、环境搭建以及实战案例。通过本文,读者可以快速掌握 Netty 的核心特性和使用方法。
Netty简介
Netty 是一个异步的事件驱动网络应用框架,用于快速开发可维护的高性能协议服务器和客户端。Netty 提供了多种传输协议的实现,包括 TCP、UDP、SSL、WebSocket 等,使得开发者可以专注于应用逻辑的实现,而不是底层网络编程的细节。
Netty 是什么
Netty 是由 JBoss 开发团队开发的一个基于 Java NIO 的异步事件驱动网络应用框架。Netty 提供了一套完整的网络传输功能,包括连接管理、数据包编码与解码、网络流控制、错误处理等,这使得开发者能够更加高效地编写高性能、可扩展的网络应用。
Netty 的特点和优势
- 异步非阻塞:Netty 使用异步非阻塞 I/O 模型,通过事件驱动的方式处理网络事件,从而实现高效的网络通信。
- 高性能:Netty 采用了内存池管理和高效的数据传输机制,保证了低延迟和高吞吐量。
- 灵活的编码和解码:Netty 支持多种协议的编码和解码,如 TCP、HTTP、WebSocket 等。
- 强大的错误处理机制:Netty 提供了灵活的异常处理机制,可以自定义异常处理器来处理各类错误。
- 易于扩展:Netty 的设计非常灵活,可以轻松地扩展新的协议和功能。
- 可插拔的组件:Netty 提供了丰富的可插拔组件,如自定义的 Socket、处理器、解码器、编码器等。
Netty 的应用场景
- 高性能服务器:Netty 常用于需要高性能的服务器应用,如网络游戏服务器、实时聊天室、在线视频直播等。
- 异步通信:Netty 可用于需要异步通信的应用场景,如远程过程调用(RPC)、微服务间通信等。
- 高并发应用:Netty 支持高并发的连接数,适用于需要大量并发连接的应用场景。
- 网络协议实现:Netty 提供了丰富的协议支持,可以用于实现各种网络协议,如 HTTP、WebSocket、FTP 等。
Netty 环境搭建
开发环境准备
在开发 Netty 应用之前,需要安装 Java 开发环境和相关的开发工具。首先确保已安装 Java 开发工具包(JDK),并设置好环境变量。可以使用以下命令检查 Java 版本:
java -version
Maven 配置及依赖引入
Netty 的依赖可以通过 Maven 中央仓库获取,添加 Maven 依赖到项目中。若你使用的是 Maven 项目,可以在 pom.xml
文件中添加以下依赖:
<dependencies>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.69.Final</version>
</dependency>
</dependencies>
IDE 配置详解
Netty 可以在多种 IDE 中进行开发,如 IntelliJ IDEA 和 Eclipse。这里以 IntelliJ IDEA 为例进行配置。
- 创建 Maven 项目:在 IntelliJ IDEA 中创建一个新的 Maven 项目,确保项目中包含了必要的 Maven 设置。
- 添加 Netty 依赖:在
pom.xml
文件中添加 Netty 依赖。 - 配置项目结构:确保项目结构正确,可以在项目视图中查看依赖是否正确导入。
示例代码如下:
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
public class SimpleServer {
public static void main(String[] args) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new SimpleHandler());
}
});
ChannelFuture f = b.bind(8080).sync();
f.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class SimpleHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ByteBuf in = (ByteBuf) msg;
try {
while (in.isReadable()) {
System.out.println((char) in.readByte());
}
} finally {
in.release();
}
}
}
Netty 核心概念
事件循环模型
Netty 使用事件循环模型(Event Loop Model)来处理网络事件。事件循环模型包含以下几个核心组件:
- 事件循环(Event Loop):每个事件循环负责一个或多个网络通道(Channel)上的 I/O 事件处理。
- 时间循环组(EventLoopGroup):一组事件循环的集合,通常用于处理多个网络连接。
- 网络通道(Channel):网络通信的基本单元,表示一个打开的连接。
- ChannelHandler:处理网络事件的处理器,包括编解码、异步 I/O 等。
Channel与ChannelHandler
Netty 中的 Channel
是一个表示网络连接的接口,每个 Channel
都有一个与之关联的 ChannelPipeline
,用于处理网络事件。
ChannelHandler
是处理网络事件的处理器,它被添加到 ChannelPipeline
中。ChannelHandler
支持多种类型的事件,如读事件、写事件等。
示例代码如下:
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
public class SimpleServer {
public static void main(String[] args) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new SimpleHandler());
}
});
ChannelFuture f = b.bind(8080).sync();
f.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class SimpleHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ByteBuf in = (ByteBuf) msg;
try {
while (in.isReadable()) {
System.out.println((char) in.readByte());
}
} finally {
in.release();
}
}
}
EventLoop与EventExecutor
EventLoop
是事件循环的核心接口,用于处理网络事件。每个 Channel
都关联到一个 EventLoop
,负责处理该通道上的 I/O 事件。
EventExecutor
是 EventLoop
的一个子接口,提供异步执行任务的能力。EventLoop
实现了 EventExecutor
接口,可以执行任务并等待任务执行完成。
示例代码如下:
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import java.util.concurrent.TimeUnit;
public class SimpleHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ctx.executor().schedule(() -> {
System.out.println("Task executed after 5 seconds");
}, 5, TimeUnit.SECONDS);
}
}
编码器与解码器(Encoder和Decoder)
Netty 提供了丰富的编码器和解码器,用于将 Java 对象与网络字节流相互转换。编码器将 Java 对象转换为字节流,而解码器将字节流转换为 Java 对象。
Netty 的编码器和解码器分为两类:自定义编码器和解码器、内置编码器和解码器。
示例代码如下:
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class SimpleDecoder extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
System.out.println("Decoded message: " + msg);
}
}
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOutboundHandlerAdapter;
public class SimpleEncoder extends ChannelOutboundHandlerAdapter {
@Override
public void write(ChannelHandlerContext ctx, Object msg, io.netty.util.concurrent.ChannelFutureListener futureListener) {
System.out.println("Encoded message: " + msg);
ctx.writeAndFlush(msg);
}
}
ByteToMessageDecoder与MessageToByteEncoder
ByteToMessageDecoder
和 MessageToByteEncoder
是 Netty 中两个常用的编码器和解码器。
ByteToMessageDecoder
:将字节流解码为 Java 对象。MessageToByteEncoder
:将 Java 对象编码为字节流。
示例代码如下:
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import java.util.List;
public class SimpleDecoder extends ByteToMessageDecoder {
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
if (in.readableBytes() >= 1) {
out.add(in.readByte());
}
}
}
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
public class SimpleEncoder extends MessageToByteEncoder<String> {
@Override
protected void encode(ChannelHandlerContext ctx, String msg, ByteBuf out) {
out.writeByte(msg.charAt(0));
}
}
Netty 实战入门
创建第一个 Netty 服务器
创建一个简单的 Netty 服务器,用于接收客户端连接并处理简单的消息。
示例代码如下:
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
public class SimpleServer {
public static void main(String[] args) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new SimpleHandler());
}
});
ChannelFuture f = b.bind(8080).sync();
f.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class SimpleHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ByteBuf in = (ByteBuf) msg;
try {
while (in.isReadable()) {
System.out.println((char) in.readByte());
}
} finally {
in.release();
}
}
}
创建第一个 Netty 客户端
创建一个简单的 Netty 客户端,用于连接服务器并发送消息。
示例代码如下:
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
public class SimpleClient {
public static void main(String[] args) throws Exception {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new SimpleHandler());
}
});
ChannelFuture f = b.connect("localhost", 8080).sync();
f.channel().closeFuture().sync();
} finally {
group.shutdownGracefully();
}
}
}
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.ChannelPromise;
public class SimpleHandler extends ChannelOutboundHandlerAdapter {
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
ByteBuf out = (ByteBuf) msg;
try {
out.writeByte('A');
out.writeByte('B');
} finally {
out.release();
}
}
}
启动与停止服务器和客户端
启动服务器和客户端时,需要确保服务器先启动并监听指定端口。客户端连接到服务器后,可以发送消息。停止服务器和客户端时,需要调用相应的关闭方法。
示例代码如下:
// 服务器启动
public class SimpleServer {
public static void main(String[] args) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new SimpleHandler());
}
});
ChannelFuture f = b.bind(8080).sync();
f.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
// 客户端启动
public class SimpleClient {
public static void main(String[] args) throws Exception {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new SimpleHandler());
}
});
ChannelFuture f = b.connect("localhost", 8080).sync();
f.channel().closeFuture().sync();
} finally {
group.shutdownGracefully();
}
}
}
数据传输
Netty 支持多种数据传输方式,包括同步传输和异步传输。可以使用 write
和 writeAndFlush
方法进行数据传输。
示例代码如下:
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class SimpleHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ByteBuf in = (ByteBuf) msg;
try {
while (in.isReadable()) {
System.out.println((char) in.readByte());
}
} finally {
in.release();
}
}
@Override
public void channelActive(ChannelHandlerContext ctx) {
ctx.writeAndFlush("Hello, World!");
}
}
异步非阻塞的特性演示
Netty 的异步非阻塞特性可以通过事件循环模型实现。事件循环模型会异步地处理网络事件,避免了阻塞操作。
示例代码如下:
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
public class SimpleServer {
public static void main(String[] args) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new SimpleHandler());
}
});
ChannelFuture f = b.bind(8080).sync();
f.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class SimpleHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ByteBuf in = (ByteBuf) msg;
try {
while (in.isReadable()) {
System.out.println((char) in.readByte());
}
} finally {
in.release();
}
}
}
Netty 常见问题与优化
常见问题解析
Netty 在使用过程中可能会遇到一些常见问题,如内存泄漏、性能瓶颈等。以下是常见问题及解决方法:
- 内存泄漏:内存泄漏通常发生在使用了不正确的内存管理方式,如不释放 ByteBuf。
- 性能瓶颈:性能瓶颈可能出现在 I/O 操作、网络延迟等方面,需要进行性能分析和优化。
- 异常处理:Netty 提供了丰富的异常处理机制,可以自定义异常处理器来处理各类错误。
- 线程模型:Netty 使用异步非阻塞模型,需要正确配置线程池和事件循环组。
- 协议问题:协议解析错误会导致数据传输失败,需要正确实现编码和解码逻辑。
性能优化策略
- 使用合适的数据结构:选择合适的数据结构,如
ByteBuf
、List
等,可以提高数据处理效率。 - 减少内存分配:尽量减少动态内存分配,使用内存池和复用对象。
- 优化网络通信:减少网络延迟,使用高效的网络协议和编码方式。
- 合理配置线程池:根据应用需求配置合适的线程池大小,避免过多线程导致资源浪费。
- 使用异步任务调度:将耗时操作异步化,避免阻塞主线程。
内存管理与调优
Netty 提供了丰富的内存管理工具,如 ByteBuf
、内存池等。合理配置内存池可以减少内存分配次数,提高内存使用效率。
示例代码如下:
import io.netty.buffer.ByteBuf;
import io.netty.buffer.CompositeByteBuf;
import io.netty.buffer.Unpooled;
public class MemoryManagement {
public static void main(String[] args) {
ByteBuf buffer = Unpooled.directBuffer(1024);
buffer.writeBytes("Hello, World!".getBytes());
CompositeByteBuf compositeBuffer = Unpooled.compositeBuffer();
compositeBuffer.addComponent(buffer);
compositeBuffer.addComponent(Unpooled.directBuffer(1024));
System.out.println(compositeBuffer.readableBytes());
compositeBuffer.release();
}
}
Netty 项目实战
小型聊天室搭建
搭建一个简单的聊天室应用,实现客户端与服务器之间的消息传输。
示例代码如下:
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
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.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
public class ChatServer {
public static void main(String[] args) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new StringEncoder());
ch.pipeline().addLast(new ChatServerHandler());
}
});
ChannelFuture f = b.bind(8080).sync();
f.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class ChatServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
String message = (String) msg;
System.out.println("Received message: " + message);
ctx.channel().writeAndFlush("Echo: " + message);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
文件传输功能实现
实现一个简单的文件传输应用,客户端向服务器发送文件,服务器接收并保存文件。
示例代码如下:
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
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.LengthFieldPrepender;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.string.StringEncoder;
public class FileServer {
public static void main(String[] args) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(1024, 0, 4, 0, 4));
ch.pipeline().addLast(new LengthFieldPrepender(4));
ch.pipeline().addLast(new FileServerHandler());
}
});
ChannelFuture f = b.bind(8080).sync();
f.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelPromise;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
public class FileServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ByteBuf in = (ByteBuf) msg;
try {
int length = in.readInt();
byte[] bytes = new byte[length];
in.readBytes(bytes);
FileChannel fileChannel = FileChannel.open(Paths.get("received_file.txt"), StandardOpenOption.CREATE, StandardOpenOption.WRITE);
fileChannel.write(ByteBuffer.wrap(bytes));
fileChannel.close();
ctx.writeAndFlush("File received");
} finally {
in.release();
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
使用 Netty 构建简单的 Web 服务器
构建一个简单的 Web 服务器,实现 HTTP 请求和响应的处理。
示例代码如下:
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
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.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
public class SimpleWebServer {
public static void main(String[] args) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new HttpServerCodec());
ch.pipeline().addLast(new HttpObjectAggregator(65536));
ch.pipeline().addLast(new SimpleWebServerHandler());
}
});
ChannelFuture f = b.bind(8080).sync();
f.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpResponse;
public class SimpleWebServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) {
String uri = msg.uri();
System.out.println("Received HTTP request: " + uri);
if (uri.equals("/hello")) {
HttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain");
response.content().writeBytes("Hello, World!".getBytes());
ctx.writeAndFlush(response);
} else {
HttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.NOT_FOUND);
ctx.writeAndFlush(response);
}
}
}
通过以上示例,可以更好地理解 Netty 的应用场景和开发方法。结合开发实践,可以进一步提升 Netty 应用的性能和稳定性。
共同学习,写下你的评论
评论加载中...
作者其他优质文章