netty+websocket sending and receiving messages

Premise: when you go to the toilet, there is only one pit, and someone takes it
IO: synchronous blocking (waiting at the door of the toilet, doing nothing, waiting for the person to come out)
NIO: synchronous non blocking (take a cigarette out of the door and go in every now and then to see if the person is out)
AIO: asynchronous non blocking (smoke at the door, the person will inform you after coming out, you can go to the toilet)

  1. Introduce maven dependency
  1. Write server code
import io.netty.bootstrap.ServerBootstrap;

public class WSServer {

    public static void main(String[] args) {
        // mainGroup is similar to the waiter at the door of the hotel (receiving the link of the client)
        EventLoopGroup mainGroup = new NioEventLoopGroup();
        // Subgroups are similar to staff in hotels. The waiter at the door brings the guests in and leaves them to him
        EventLoopGroup subGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap server = new ServerBootstrap();
  , subGroup)
                    // After opening the room, take the guests upstairs (open a passage)
                    // Help the guest to open the door at the door of the room (follow-up processing)
                    .childHandler(new WSServerInitialize());

            ChannelFuture future = server.bind(8088).sync();
        } catch (Exception e) {
        } finally {


  1. Initialize client's link
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;

public class WSServerInitialize extends ChannelInitializer<SocketChannel> {

    protected void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();

        // websocket is based on http protocol, so http decoder is needed
        pipeline.addLast(new HttpServerCodec());
        // Support for writing big data stream
        pipeline.addLast(new ChunkedWriteHandler());
        // Aggregate httpMessage into FullHttpRequest or FullHttpResponse
        // This handler is used almost in netty programming
        pipeline.addLast(new HttpObjectAggregator(1024 * 64));

         * websocket Server processing protocol, used to assign routes to client access: / ws
         * This handler will help you deal with some heavy and complicated things
         * handshaking(ping, pong, close)ping + pong = heartbeat
         * For websocket, it is transmitted through frames, and the frames corresponding to different data types are also different
        pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));

        // Custom handler
        pipeline.addLast(new ChatHandler());

  1. Customizing links for processing clients
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;

import java.time.LocalDateTime;

public class ChatHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

    // channel for logging and managing all clients
    private static ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    protected void channelRead0(ChannelHandlerContext channelHandlerContext, TextWebSocketFrame msg) throws Exception {
        // Get the message from the client
        String content = msg.text();
        System.out.println("Data received:" + content);

        for (Channel channel : clients) {
            channel.writeAndFlush(new TextWebSocketFrame("Server side
			[" + + "]Message received, message:" + content));

     * After the client connects to the server (open the link)
     * Get the channel of the client and put it into the channelGroup for management
     * @param ctx
     * @throws Exception
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {

    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        // When handlerRemoved is triggered, ChannelGroup will automatically remove the channel of the corresponding client
        // clients.remove(;
        System.out.println("Client disconnected, channel Corresponding length ID For:" +;
        System.out.println("Client disconnected, channel Corresponding short ID For:" +;
  1. Write page tests
<!DOCTYPE html>
	<meta charset="utf-8">
	<div>send message</div>
	<input type="text" id="msgContent">
	<input type="button" value="Click me to send" onclick=";">
	<div>Receive message:</div>
	<div id="receiveMsg" style="background-color: yellow;"></div>

	<script type="text/javascript">
		window.CHAT = {
			socket: null,
			init: function() {
				if (window.WebSocket) {
					CHAT.socket = new WebSocket("ws://");
					CHAT.socket.onopen = function() {
						console.log("connect success...");
					CHAT.socket.onclose = function() {
						console.log("connect close...");
					CHAT.socket.onerror = function() {
						console.log("connect error...");
					CHAT.socket.onmessage = function(e) {
						console.log("receive msg: " +;
						var receiveMsg = document.getElementById("receiveMsg");
						var html = receiveMsg.innerHTML;
						receiveMsg.innerHTML = html + "<br />" +;
				} else {
					alert("do not support websocket..");
			chat: function() {
				var msgContent = document.getElementById("msgContent");

Tags: Programming Netty socket codec Maven

Posted on Mon, 23 Mar 2020 10:31:02 -0400 by shaneH