Understanding Netty: Core Components, Architecture, and a Simple Chat Server Example
This tutorial explains why Netty is preferred over raw NIO, introduces its core components and architecture, and walks through a complete Java example of a simple Netty chat server, including handling of connections, message broadcasting, pipeline configuration, and TCP sticky‑packet issues.
In this article the author revisits Netty after a previous NIO discussion, explaining why Netty is preferred and providing a complete walkthrough of a simple chat server implementation.
It starts with a full Java source of a NettyChatServer, highlighting the use of EventLoopGroup , ServerBootstrap , ChannelInitializer , and custom handlers ( ChatNettyHandler , ChatHolder ) to manage connections, message broadcasting, and user join/quit logic.
The core Netty components are then described: Bootstrap & ServerBootstrap , EventLoopGroup & EventLoop , ByteBuf (pooled vs unpooled, heap vs direct), Channel and its subclasses ( NioServerSocketChannel , NioSocketChannel ), ChannelHandler (inbound/outbound), ChannelPipeline , and ChannelHandlerContext , including how they are linked and how to modify the pipeline.
Special attention is given to TCP sticky‑packet issues (packet fragmentation and aggregation) and how Netty provides decoders such as FixedLengthFrameDecoder , DelimiterBasedFrameDecoder , and LengthFieldBasedFrameDecoder to solve them, with a concrete delimiter‑based echo server example:
public class DelimiterEchoServer {
public static final String DELIMITER_SYMBOL = "@~";
public static final int PORT = 9997;
public static void main(String[] args) throws InterruptedException {
EventLoopGroup group = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(group)
.channel(NioServerSocketChannel.class)
.localAddress(new InetSocketAddress(PORT))
.childHandler(new ChannelInitializer
() {
@Override
protected void initChannel(Channel ch) throws Exception {
ByteBuf delimiter = Unpooled.copiedBuffer(DELIMITER_SYMBOL.getBytes());
ch.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, delimiter));
ch.pipeline().addLast(new DelimiterServerHandler());
}
});
ChannelFuture f = b.bind().sync();
f.channel().closeFuture().sync();
} finally {
group.shutdownGracefully().sync();
}
}
}Finally the article outlines the step‑by‑step server bootstrap process, from creating EventLoopGroups to binding the port and shutting down gracefully, and concludes with references to Netty books, online courses, and open‑source repositories.
Wukong Talks Architecture
Explaining distributed systems and architecture through stories. Author of the "JVM Performance Tuning in Practice" column, open-source author of "Spring Cloud in Practice PassJava", and independently developed a PMP practice quiz mini-program.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.