niezhiliang / netty-websocket-spring-boot

♨️基于Netty实现的websocket消息推送,单独发送信息,群发信息
418 stars 221 forks source link

netty-websocket-spring-boot

前言

该项目之前是基于spring-boot-starter-websocket做的一个Demo,start还不错, 偶然间看到大佬基于 Netty实现了一个轻量级高性能的Netty-Websocket框架, 而且用法和spring-boot-starter-websocket一样,注解驱动,看到后感触很大, 觉得他很牛逼,看了下他的源码, 大致原理和技术知道了以后,我之前也看过很多spring相关源码,觉得我应该也能写出来,于是就强迫自己重写了该项目,也算是 对源码的巩固,太久不看,确实很多又忘了。

介绍

基于Netty实现了大部分spring-websocket的功能,从下图能知道Spring-Websocket使用起来非常方便,但是性能方面相较于Netty实现的WebScoket性能会有 些差距,但是Netty做Websocket复杂度更高,为了让Netty实现WebSocket使用更简单,于是开发了这个starter,该starter使用起来可以和 spring-websocket一样简单,而且使用语法尽可能的和Spring-Websocket一致。

演示gif

使用

支持事件类型

事件 事件注解 应用场景
握手前 @HandshakeBefore 认证、鉴权
连接成功 @OnOpen --
收到消息 @OnMessage --
连接关闭 @OnClose
异常 @OnError 异常捕获
心跳超时 @OnEvent 剔除失效连接

注解方法支持的参数类型

参数 @HandshakeBefore @OnOpen @OnClose @OnMessage @OnEvent @OnError
HttpHeaders
Session
@PathParam
String(消息内容) × × × × ×
Throwable × × × × ×
Object(事件) × × × × ×

添加maven依赖

<dependency>
    <groupId>com.niezhiliang</groupId>
    <artifactId>netty-websocket-spring-boot-starter</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>
@WsServerEndpoint(value = "/websocket/{uid}/{arg}")
public class ServerEndpoint {

    @HandshakeBefore
    public void before (HttpHeaders headers) {
        System.out.println("before");
    }

    /**
     * 用户连接时触发
     * @param session
     */
    @OnOpen
    public void open(Session session, @PathParam (value="uid") String uid, @PathParam String arg){
        System.out.println("open");
        session.sendText("hello client");
    }

    /**
     * 收到信息时触发
     * @param message
     */
    @OnMessage
    public void onMessage(Session session,String message){
        System.out.println("message:" + message);
        session.sendText("server: " + message);
    }

    /**
     * 连接关闭触发
     */
    @OnClose
    public void onClose(){
        System.out.println("close  " + LocalDateTime.now());
    }

    /**
     * 发生错误时触发
     * @param session
     * @param e
     */
    @OnError
    public void onError(Session session, Throwable e) {
        System.out.println("onError");
    }

    /**
     * 发生事件时触发
     * @param session
     * @param evt
     */
    @OnEvent
    public void onEvent(Session session, Object evt) {
        if (evt instanceof IdleStateEvent) {
            // 心跳事件处理
        }
    }
}

收获

演示gif