在前兩篇文章中,我們深入探討了 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 在處理多客戶端通信方面的強大能力。在實際應用中,可以在此基礎上擴展更多功能,如用戶認證、私聊、群聊等。