@IT·互联网全栈程序猿的成长

websocket离线数据推送

2024-09-13  本文已影响0人  小尘哥

之前写了两篇关于websocket消息推送的,忽略了一个离线消息处理的问题,今天补上,其实思路很简单:发送消息的时候若对方不在线,先暂存消息,等对方在线的时候再进行推送。

前文连接

  1. 若依(ruoyi)使用websocket推送数据到前端 - 简书 (jianshu.com)
  2. websocket点对点消息推送 - 简书 (jianshu.com)

我这里写的只是思路,相对比较简单,若真实做系统还需要考虑大量session会话如何保持、多条消息先后顺序,不同人推送给同一个人如何标记,消息如何格式化等等。

@Component
@ServerEndpoint(value = "/mos/websocket/{userId}")
@Slf4j
public class WebSocket {
    private static Map<String, Session> livingSession = new ConcurrentHashMap<>();

    private static Map<String, String> CACHE_MESSAGE = new ConcurrentHashMap<>();

    /**
     * 客户端与服务端连接成功
     *
     * @param session
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId) {

        livingSession.put(userId, session);

        // 判断是否有离线消息,再进行推送
        String offLineMessage = CACHE_MESSAGE.get(userId);
        if (offLineMessage != null) {
            session.getAsyncRemote().sendText(offLineMessage + " 看到消息时间:" + DateUtil.now());
            // 清空消息,避免下次上线重复推送
            CACHE_MESSAGE.remove(userId);
        }
    }

    /**
     * 客户端与服务端连接关闭
     *
     * @param session
     */
    @OnClose
    public void onClose(Session session, @PathParam("userId") String userId) {
        livingSession.remove(userId);
    }

    /**
     * 客户端与服务端连接异常
     *
     * @param error
     * @param session
     */
    @OnError
    public void onError(Throwable error, Session session) {
        error.printStackTrace();
    }

    /**
     * 客户端向服务端发送消息
     *
     * @param message
     * @throws IOException
     */
    @OnMessage
    public void onMsg(String msg) throws IOException {
        MsgEntity msgEntity = JSONUtil.toBean(msg,MsgEntity.class);
        Session session = livingSession.get(msgEntity.getReceiveUserId());
        String msgFmt  = "%s --来自【%s】的消息,现在时间:%s";
        String formatMsg = String.format(msgFmt,msgEntity.getMsg(),msgEntity.getUserId(), DateUtil.now());
        if (session != null) {
            session.getAsyncRemote().sendText(formatMsg);
        }else{
            // 消息暂存
            CACHE_MESSAGE.put(msgEntity.getReceiveUserId(),formatMsg);
        }

    }

}

完整代码见MosSimple: 功能示例 (gitee.com)

上一篇下一篇

猜你喜欢

热点阅读