All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.dengchen2020.websocket.BaseWebSocketHandler Maven / Gradle / Ivy

There is a newer version: 0.0.28
Show newest version
package io.github.dengchen2020.websocket;

import jakarta.websocket.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * websocket注解方式处理器
 *
 * @author dengchen
 * @since 2024/6/5
 */
public class BaseWebSocketHandler {

    /**
     * 在 WebSocket 协商成功且 WebSocket 连接打开并可供使用后调用
     *
     * @param session websocket会话
     * @param config  websocket端点配置
     */
    @OnOpen
    public void onOpen(Session session, EndpointConfig config) {
        if (session.getUserPrincipal() == null) {
            CloseReason closeReason = new CloseReason(CloseReason.CloseCodes.VIOLATED_POLICY, "获取Token认证信息失败,请重新登录");
            onlineFailEvent(session, closeReason);
            close(session, closeReason);
            return;
        }
        initSessionConfig(session);
        getSessions().put(online(session), session);
        onlineSuccessEvent(session);
    }

    /**
     * 接收文本消息
     *
     * @param session websocket会话
     * @param message 文本消息
     */
    @OnMessage
    public void onMessage(Session session, String message) {
        if (log.isDebugEnabled()) log.debug("收到文本消息:{}", message);
    }

    /**
     * 接收pong消息
     *
     * @param session websocket会话
     * @param message pong消息
     */
    @OnMessage
    public void onMessage(Session session, PongMessage message) {
        if (log.isDebugEnabled()) log.debug("收到pong消息:{}", message.getApplicationData());
    }

    /**
     * 接收二进制数据消息
     *
     * @param session websocket会话
     * @param message 二进制数据消息
     */
    @OnMessage
    public void onMessage(Session session, ByteBuffer message) {
        if (log.isDebugEnabled()) log.debug("收到二进制数据消息:{}", message);
    }

    @OnClose
    public void onClose(Session session, CloseReason closeReason) {
        getSessions().values().remove(session);
        close(session);
        if (CLOSE_CODE.contains(closeReason.getCloseCode().getCode())) {
            if (log.isDebugEnabled()) log.debug("连接关闭,原因是:{}", closeReason);
        } else {
            log.warn("连接关闭,原因是:{}", closeReason);
        }
    }

    /**
     * 发生异常时回调
     *
     * @param session websocket会话
     * @param error   异常
     */
    @OnError
    public void onError(Session session, Throwable error) {
        if (log.isDebugEnabled()) log.debug("连接发生异常,原因是:{}", error.toString());
    }

    private static final Logger log = LoggerFactory.getLogger(BaseWebSocketHandler.class);

    private static final Map sessions = new ConcurrentHashMap<>();

    private final Set CLOSE_CODE = Set.of(CloseReason.CloseCodes.NORMAL_CLOSURE.getCode(), CloseReason.CloseCodes.GOING_AWAY.getCode(), CloseReason.CloseCodes.CLOSED_ABNORMALLY.getCode(), CloseReason.CloseCodes.VIOLATED_POLICY.getCode());

    @SuppressWarnings("unchecked")
    public  Map getSessions() {
        return (Map) sessions;
    }

    /**
     * 初始化会话配置
     *
     * @param session websocket会话
     */
    public void initSessionConfig(Session session) {
        session.setMaxIdleTimeout(90 * 1000);
        session.setMaxTextMessageBufferSize(16 * 1024);
        session.setMaxBinaryMessageBufferSize(1024 * 1024);
        session.getAsyncRemote().setSendTimeout(10 * 1000);
    }

    /**
     * 上线
     *
     * @param session websocket会话
     * @return websocket客户端信息
     */
    public  DefaultWebSocketClientInfo online(Session session) {
        return new DefaultWebSocketClientInfo(session.getId());
    }

    /**
     * 上线成功事件
     *
     * @param session websocket会话
     */
    public void onlineSuccessEvent(Session session) {
        if (log.isDebugEnabled()) log.debug("客户端{}上线成功", session.getId());
    }

    /**
     * 上线失败事件
     *
     * @param session     websocket会话
     * @param closeReason 异常原因状态代码
     */
    public void onlineFailEvent(Session session, CloseReason closeReason) {
        if (log.isDebugEnabled()) log.debug("客户端{}上线失败", session.getId());
    }

    /**
     * 获取客户端信息
     *
     * @param session websocket会话
     * @return 客户端信息
     */
    public DefaultWebSocketClientInfo getClientInfo(Session session) {
        return new DefaultWebSocketClientInfo(session.getId());
    }

    /**
     * 关闭连接
     *
     * @param session websocket会话
     */
    public void close(Session session, CloseReason closeReason) {
        try {
            session.close(closeReason);
        } catch (IOException e) {
            log.error("关闭连接失败,异常信息:{}", e.getMessage());
        }
    }

    /**
     * 关闭连接
     *
     * @param session websocket会话
     */
    public void close(Session session) {
        try {
            session.close();
        } catch (IOException e) {
            log.error("关闭连接失败,异常信息:{}", e.getMessage());
        }
    }

    /**
     * 发送ping消息
     *
     * @param session websocket会话
     */
    public void sendPing(Session session) {
        try {
            session.getAsyncRemote().sendPing(ByteBuffer.allocate(1));
        } catch (Exception e) {
            log.error("发送ping消息失败:{}", e.getMessage());
        }
    }

    /**
     * 发送pong消息
     *
     * @param session websocket会话
     */
    public void sendPong(Session session) {
        try {
            session.getAsyncRemote().sendPong(ByteBuffer.allocate(1));
        } catch (Exception e) {
            log.error("发送pong消息失败:{}", e.getMessage());
        }
    }

    /**
     * 向用户发送文本消息
     *
     * @param session websocket会话
     * @param message 文本消息
     */
    public void send(Session session, String message) {
        try {
            session.getAsyncRemote().sendText(message);
        } catch (Exception e) {
            log.error("发送文本消息失败:{},异常信息:{}", message, e.getMessage());
        }
    }

    /**
     * 向用户发送二进制消息
     *
     * @param session    websocket会话
     * @param byteBuffer 二进制数据
     */
    public void send(Session session, ByteBuffer byteBuffer) {
        try {
            session.getAsyncRemote().sendBinary(byteBuffer);
        } catch (Exception e) {
            log.error("发送二进制数据消息失败:{},异常信息:{}", byteBuffer, e.getMessage());
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy