It is a code refactoring and feature enhancement for the original netty-websocket-spring-boot-starter.
Thank you very much for the author's sharing of netty-websocket-spring-boot-starter.
Developing a WebSocket server using Netty in Spring Boot, with the simplicity and high performance of spring-websocket annotations.
- jdk >= 1.8 (compatible with jdk 17、21)
 
- Add dependencies:
 
<dependency>
    <groupId>cn.twelvet</groupId>
    <artifactId>netty-websocket-spring-boot-starter</artifactId>
    <version>${version}</version>
</dependency>- Add the 
@WebSocketEndpointannotation to the endpoint class, and add the@BeforeHandshake、@OnOpen、@OnClose、@OnError、@OnMessage、@OnBinaryand@OnEventannotations to the respective methods. Here's an example: - Use 
@PathVariableto retrieve path parameters and@RequestParamto retrieve query parameters, both of which have the same effect as the corresponding Spring annotations (Note: Use the annotations provided by this framework, not Spring's annotations). 
import cn.twelvet.websocket.netty.annotation.*;
import cn.twelvet.websocket.netty.domain.NettySession;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.timeout.IdleStateEvent;
import org.springframework.util.MultiValueMap;
import java.util.Map;
@WebSocketEndpoint(path = "/ws")
public class MyWebSocket {
    @BeforeHandshake
    public void handshake(NettySession nettySession, HttpHeaders headers, @RequestParam String req, @RequestParam MultiValueMap reqMap, @PathVariable String arg, @PathVariable Map pathMap) {
        nettySession.setSubprotocols("stomp");
        if (!"ok".equals(req)) {
            System.out.println("Authentication failed!");
            // nettySession.close();
        }
    }
    @OnOpen
    public void onOpen(NettySession nettySession, HttpHeaders headers, @RequestParam String req, @RequestParam MultiValueMap reqMap, @PathVariable String arg, @PathVariable Map pathMap) {
        System.out.println("new connection");
        System.out.println(req);
    }
    @OnClose
    public void onClose(NettySession nettySession) {
        System.out.println("one connection closed");
    }
    @OnError
    public void onError(NettySession nettySession, Throwable throwable) {
        throwable.printStackTrace();
    }
    @OnMessage
    public void onMessage(NettySession nettySession, String message) {
        System.out.println(message);
        nettySession.sendText("Hello Netty!");
    }
    @OnBinary
    public void onBinary(NettySession nettySession, byte[] bytes) {
        for (byte b : bytes) {
            System.out.println(b);
        }
        nettySession.sendBinary(bytes);
    }
    @OnEvent
    public void onEvent(NettySession nettySession, Object evt) {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent idleStateEvent = (IdleStateEvent) evt;
            switch (idleStateEvent.state()) {
                case READER_IDLE:
                    System.out.println("read idle");
                    break;
                case WRITER_IDLE:
                    System.out.println("write idle");
                    break;
                case ALL_IDLE:
                    System.out.println("all idle");
                    break;
                default:
                    break;
            }
        }
    }
}- Open the WebSocket client and connect to 
ws://127.0.0.1:80/ws/xxx 
- base on Quick-Start,use annotation 
@WebSocketEndpointin classes which hope to become a endpoint. - you can get all socket addresses in 
WebSocketEndpointExporter.getAddressWebsocketServerMap(). - when there are different addresses(different host or different port) in WebSocket,they will use different 
ServerBootstrapinstance. - when the addresses are the same,but path is different,they will use the same 
ServerBootstrapinstance. - when multiple port of endpoint is 0 ,they will use the same random port
 - when multiple port of endpoint is the same as the path,host can't be set as "0.0.0.0",because it means it binds all of the addresses
 
All parameters can be obtained from the configuration in
application.ymlusing${...}placeholders. Here's an example::
- First, use 
${...}placeholders in the attributes of the@WebSocketEndpointannotation. 
@WebSocketEndpoint(host = "${ws.host}", port = "${ws.port}")
public class MyWebSocket {
    ...
}- Next, you can configure it in the 
application.ymlfile. 
ws:
  host: 0.0.0.0
  port: 80