Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/yeautyye/netty-websocket-spring-boot-starter
:rocket: lightweight high-performance WebSocket framework ( 轻量级、高性能的WebSocket框架)
https://github.com/yeautyye/netty-websocket-spring-boot-starter
annotation asynchronous chat im netty netty-spring-boot-starter spring-boot spring-boot-starter spring-boot-websocket websocket
Last synced: 6 days ago
JSON representation
:rocket: lightweight high-performance WebSocket framework ( 轻量级、高性能的WebSocket框架)
- Host: GitHub
- URL: https://github.com/yeautyye/netty-websocket-spring-boot-starter
- Owner: YeautyYE
- License: apache-2.0
- Created: 2018-07-02T02:17:43.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2023-11-25T03:07:59.000Z (about 1 year ago)
- Last Synced: 2024-12-26T17:05:38.139Z (27 days ago)
- Topics: annotation, asynchronous, chat, im, netty, netty-spring-boot-starter, spring-boot, spring-boot-starter, spring-boot-websocket, websocket
- Language: Java
- Homepage:
- Size: 147 KB
- Stars: 1,835
- Watchers: 59
- Forks: 545
- Open Issues: 163
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
netty-websocket-spring-boot-starter [![License](http://img.shields.io/:license-apache-brightgreen.svg)](http://www.apache.org/licenses/LICENSE-2.0.html)
===================================[中文文档](https://github.com/YeautyYE/netty-websocket-spring-boot-starter/blob/master/README_zh.md) (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:
```xml
org.yeauty
netty-websocket-spring-boot-starter
0.12.0
```- annotate `@ServerEndpoint` on endpoint class,and annotate `@BeforeHandshake`,`@OnOpen`,`@OnClose`,`@OnError`,`@OnMessage`,`@OnBinary`,`@OnEvent` on the method. e.g.
```java
@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](#configuration) 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](#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`
```java
@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/
| +
+- 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/
| +
+- resources/
+- public/
+- error/
| +- 404.html
| +- 5xx.html
+-
```### Multi Endpoint
- base on [Quick-Start](#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`