Awesome Open Source
Awesome Open Source

netty-websocket-spring-boot-starter License

中文文档 (Chinese Docs)

About

netty-websocket-spring-boot-starter will help you develop WebSocket server by using Netty in spring-boot,it is easy to develop by using annotation like spring-websocket

Requirement

  • jdk version 1.8 or 1.8+

Quick Start

  • add Dependencies:
	<dependency>
		<groupId>org.yeauty</groupId>
		<artifactId>netty-websocket-spring-boot-starter</artifactId>
		<version>0.12.0</version>
	</dependency>
  • annotate @ServerEndpoint on endpoint class,and annotate @BeforeHandshake,@OnOpen,@OnClose,@OnError,@OnMessage,@OnBinary,@OnEvent on the method. e.g.
@ServerEndpoint(path = "/ws/{arg}")
public class MyWebSocket {

    @BeforeHandshake
    public void handshake(Session session, HttpHeaders headers, @RequestParam String req, @RequestParam MultiValueMap reqMap, @PathVariable String arg, @PathVariable Map pathMap){
        session.setSubprotocols("stomp");
        if (!"ok".equals(req)){
            System.out.println("Authentication failed!");
            session.close();
        }
    }
    
    @OnOpen
    public void onOpen(Session session, 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(Session session) throws IOException {
       System.out.println("one connection closed"); 
    }

    @OnError
    public void onError(Session session, Throwable throwable) {
        throwable.printStackTrace();
    }

    @OnMessage
    public void onMessage(Session session, String message) {
        System.out.println(message);
        session.sendText("Hello Netty!");
    }

    @OnBinary
    public void onBinary(Session session, byte[] bytes) {
        for (byte b : bytes) {
            System.out.println(b);
        }
        session.sendBinary(bytes); 
    }

    @OnEvent
    public void onEvent(Session session, 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;
            }
        }
    }

}
  • use Websocket client to connect ws://127.0.0.1:80/ws/xxx

Annotation

@ServerEndpoint

declaring ServerEndpointExporter in Spring configuration,it will scan for WebSocket endpoints that be annotated with ServerEndpoint . beans that be annotated with ServerEndpoint will be registered as a WebSocket endpoint. all configurations are inside this annotation ( e.g. @ServerEndpoint("/ws") )

@BeforeHandshake

when there is a connection accepted,the method annotated with @BeforeHandshake will be called
classes which be injected to the method are:Session,HttpHeaders...

@OnOpen

when there is a WebSocket connection completed,the method annotated with @OnOpen will be called
classes which be injected to the method are:Session,HttpHeaders...

@OnClose

when a WebSocket connection closed,the method annotated with @OnClose will be called classes which be injected to the method are:Session

@OnError

when a WebSocket connection throw Throwable, the method annotated with @OnError will be called classes which be injected to the method are:Session,Throwable

@OnMessage

when a WebSocket connection received a message,the method annotated with @OnMessage will be called classes which be injected to the method are:Session,String

@OnBinary

when a WebSocket connection received the binary,the method annotated with @OnBinary will be called classes which be injected to the method are:Session,byte[]

@OnEvent

when a WebSocket connection received the event of Netty,the method annotated with @OnEvent will be called classes which be injected to the method are:Session,Object

Configuration

all configurations are configured in @ServerEndpoint's property

property default description
path "/" path of WebSocket can be aliased for value
host "0.0.0.0" host of WebSocket."0.0.0.0" means all of local addresses
port 80 port of WebSocket。if the port equals to 0,it will use a random and available port(to get the port Multi-Endpoint)
bossLoopGroupThreads 0 num of threads in bossEventLoopGroup
workerLoopGroupThreads 0 num of threads in workerEventLoopGroup
useCompressionHandler false whether add WebSocketServerCompressionHandler to pipeline
optionConnectTimeoutMillis 30000 the same as ChannelOption.CONNECT_TIMEOUT_MILLIS in Netty
optionSoBacklog 128 the same as ChannelOption.SO_BACKLOG in Netty
childOptionWriteSpinCount 16 the same as ChannelOption.WRITE_SPIN_COUNT in Netty
childOptionWriteBufferHighWaterMark 64*1024 the same as ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK in Netty,but use ChannelOption.WRITE_BUFFER_WATER_MARK in fact.
childOptionWriteBufferLowWaterMark 32*1024 the same as ChannelOption.WRITE_BUFFER_LOW_WATER_MARK in Netty,but use ChannelOption.WRITE_BUFFER_WATER_MARK in fact.
childOptionSoRcvbuf -1(mean not set) the same as ChannelOption.SO_RCVBUF in Netty
childOptionSoSndbuf -1(mean not set) the same as ChannelOption.SO_SNDBUF in Netty
childOptionTcpNodelay true the same as ChannelOption.TCP_NODELAY in Netty
childOptionSoKeepalive false the same as ChannelOption.SO_KEEPALIVE in Netty
childOptionSoLinger -1 the same as ChannelOption.SO_LINGER in Netty
childOptionAllowHalfClosure false the same as ChannelOption.ALLOW_HALF_CLOSURE in Netty
readerIdleTimeSeconds 0 the same as readerIdleTimeSeconds in IdleStateHandler and add IdleStateHandler to pipeline when it is not 0
writerIdleTimeSeconds 0 the same as writerIdleTimeSeconds in IdleStateHandler and add IdleStateHandler to pipeline when it is not 0
allIdleTimeSeconds 0 the same as allIdleTimeSeconds in IdleStateHandler and add IdleStateHandler to pipeline when it is not 0
maxFramePayloadLength 65536 Maximum allowable frame payload length.
useEventExecutorGroup true Whether to use another thread pool to perform time-consuming synchronous business logic
eventExecutorGroupThreads 16 num of threads in bossEventLoopGroup
sslKeyPassword ""(mean not set) the same as server.ssl.key-password in spring-boot
sslKeyStore ""(mean not set) the same as server.ssl.key-store in spring-boot
sslKeyStorePassword ""(mean not set) the same as server.ssl.key-store-password in spring-boot
sslKeyStoreType ""(mean not set) the same as server.ssl.key-store-type in spring-boot
sslTrustStore ""(mean not set) the same as server.ssl.trust-store in spring-boot
sslTrustStorePassword ""(mean not set) the same as server.ssl.trust-store-password in spring-boot
sslTrustStoreType ""(mean not set) the same as server.ssl.trust-store-type in spring-boot
corsOrigins {}(mean not set) the same as @CrossOrigin#origins in spring-boot
corsAllowCredentials ""(mean not set) the same as @CrossOrigin#allowCredentials in spring-boot

Configuration by application.properties

You can get the configurate of application.properties by using ${...} placeholders. for example:

  • first,use ${...} in @ServerEndpoint
@ServerEndpoint(host = "${ws.host}",port = "${ws.port}")
public class MyWebSocket {
    ...
}
  • then configurate in application.properties
ws.host=0.0.0.0
ws.port=80

Custom Favicon

The way of configure favicon is the same as spring-boot.If favicon.ico is presented in the root of the classpath,it will be automatically used as the favicon of the application.the example is following:

src/
  +- main/
      +- java/
      |   + <source code>
      +- resources/
          +- favicon.ico

Custom Error Pages

The way of configure favicon is the same as spring-boot.you can add a file to an /public/error folder.The name of the error page should be the exact status code or a series mask.the example is following:

src/
  +- main/
      +- java/
      |   + <source code>
      +- resources/
          +- public/
              +- error/
              |   +- 404.html
              |   +- 5xx.html
              +- <other public assets>

Multi Endpoint

  • base on Quick-Start,use annotation @ServerEndpoint and @Component in classes which hope to become a endpoint.
  • you can get all socket addresses in ServerEndpointExporter.getInetSocketAddressSet().
  • when there are different addresses(different host or different port) in WebSocket,they will use different ServerBootstrap instance.
  • when the addresses are the same,but path is different,they will use the same ServerBootstrap instance.
  • 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

Change Log

0.8.0

  • Auto-Configuration

0.9.0

  • Support RESTful by @PathVariable
  • Get param by@RequestParam from query
  • Remove ParameterMap ,instead of @RequestParam MultiValueMap
  • Add @BeforeHandshake annotation,you can close the connect before handshake
  • Set sub-protocol in @BeforeHandshake event
  • Remove the @Component on endpoint class
  • Update Netty version to 4.1.44.Final

0.9.1

  • Bug fixed : it was null when using @RequestParam MultiValueMap to get value
  • Update Netty version to 4.1.45.Final

0.9.2

  • There are compatibility version under 0.8.0 that can configure the ServerEndpointExporter manully

0.9.3

  • Bug fixed :when there is no @BeforeHandshake , NullPointerException will appear

0.9.4

  • Bug fixed :when there is no @BeforeHandshake , Session in OnOpen is null

0.9.5

  • Bug fixed :Throwable in OnError event is null

0.10.0

  • Modified the default value of bossLoopGroupThreads to 1
  • Supports configuring useEventExecutorGroup to run synchronous and time-consuming business logic in EventExecutorGroup, so that the I/O thread is not blocked by a time-consuming task
  • SSL supported
  • CORS supported
  • Update Netty version to 4.1.49.Final

0.11.0

  • When the ServerEndpoint class is proxied by CGLIB (as with AOP enhancement), it still works

0.12.0

  • @enableWebSocket adds the scanBasePackages attribute
  • @serverEndpoint no longer depends on @Component
  • Update Netty version to 4.1.67.Final

Get A Weekly Email With Trending Projects For These Topics
No Spam. Unsubscribe easily at any time.
Java (706,068
Spring Boot (12,128
Websocket (5,264
Chat (3,217
Annotations (1,296
Asynchronous (1,270
Netty (815
Im (275
Spring Boot Starter (224
Related Projects