在前两篇文章中,我们深入探讨了 Netty 的 IO 模型以及其核心组件的工作原理。本篇文章将通过一个实际的聊天服务器示例,展示如何使用 Netty 构建高性能的网络应用。
一、项目结构
项目主要包含以下几个部分:
-
ChatServer:服务器启动类
-
ChatServerInitializer:初始化通道的处理器
-
ChatServerHandler:处理业务逻辑
二、服务器启动类
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 ChatServerInitializer());ChannelFuture f = b.bind(8000).sync();f.channel().closeFuture().sync();} finally {bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}
}
上述代码中,我们创建了两个事件循环组:bossGroup用于接受客户端连接,workerGroup 用于处理已连接的客户端的网络读写。通过 ServerBootstrap 配置服务器,并绑定端口 8000。
三、通道初始化器
public class ChatServerInitializer extends ChannelInitializer<SocketChannel> {@Overrideprotected void initChannel(SocketChannel ch) {ChannelPipeline pipeline = ch.pipeline();pipeline.addLast(new StringDecoder());pipeline.addLast(new StringEncoder());pipeline.addLast(new ChatServerHandler());}
}
在通道初始化器中,我们添加了三个处理器:StringDecoder 用于将字节解码为字符串,StringEncoder 用于将字符串编码为字节,ChatServerHandler 用于处理业务逻辑。
四、业务逻辑处理器
public class ChatServerHandler extends SimpleChannelInboundHandler<String> {private static ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);@Overridepublic void handlerAdded(ChannelHandlerContext ctx) {Channel incoming = ctx.channel();channels.writeAndFlush("[SERVER] - " + incoming.remoteAddress() + " 加入\n");channels.add(incoming);}@Overridepublic void handlerRemoved(ChannelHandlerContext ctx) {Channel incoming = ctx.channel();channels.writeAndFlush("[SERVER] - " + incoming.remoteAddress() + " 离开\n");channels.remove(incoming);}@Overrideprotected void channelRead0(ChannelHandlerContext ctx, String msg) {Channel incoming = ctx.channel();for (Channel channel : channels) {if (channel != incoming) {channel.writeAndFlush("[" + incoming.remoteAddress() + "] " + msg + "\n");} else {channel.writeAndFlush("[你] " + msg + "\n");}}}
}
在 ChatServerHandler 中,我们使用 ChannelGroup 来管理所有连接的客户端。当有新的客户端连接或断开时,服务器会广播相应的消息。当服务器接收到某个客户端发送的消息时,会将该消息广播给所有其他客户端。
五、测试聊天服务器
启动服务器后,可以使用多个客户端(如 Telnet)连接到服务器:
telnet localhost 8000
连接成功后,输入的消息将被广播给所有其他已连接的客户端。
六、总结
通过本篇文章,我们实现了一个基于 Netty 的简易聊天服务器,展示了 Netty 在处理多客户端通信方面的强大能力。在实际应用中,可以在此基础上扩展更多功能,如用户认证、私聊、群聊等。