package com.ard.work.websocket.utils; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import lombok.extern.slf4j.Slf4j; import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketSession; import java.io.IOException; import java.net.InetSocketAddress; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.Executor; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @ClassName WebSocketUtils * @Description: websocket工具类 * @Author 刘苏义 * @Date 2023/1/27 7:46 * @Version 1.0 */ @Slf4j public final class PTZWebSocketUtils { public static final ConcurrentMap ONLINE_USER_SESSIONS = new ConcurrentHashMap<>(); /** 推送线程池,由 PTZWebSocketInitializer 在启动时注入;未注入时降级为同步执行 */ private static volatile Executor pushExecutor; public static void setPushExecutor(Executor executor) { pushExecutor = executor; } public static void sendMessage(WebSocketSession session, String message) { if (session == null) { return; } final InetSocketAddress remoteAddress = session.getRemoteAddress(); if (remoteAddress == null) { return; } synchronized (session) { try { session.sendMessage(new TextMessage(message)); } catch (IOException e) { log.error("sendMessage IOException ", e); } } } public static void sendMessage(WebSocketSession session, Map message) { sendMessage(session, JSONObject.toJSONString(message)); } public static void sendMessage(WebSocketSession session, List message) { sendMessage(session, JSON.toJSONString(message)); } /** * 推送字符串消息到所有客户端 */ public static void sendMessageAll(String message) { broadcast(message); } /** * 推送Map消息到所有客户端 */ public static void sendMessageAll(Map message) { broadcast(JSONObject.toJSONString(message)); } /** * 推送List消息到所有客户端 */ public static void sendMessageAll(List message) { broadcast(JSON.toJSONString(message)); } /** * 一次序列化,并行分发到所有 session */ private static void broadcast(String payload) { if (ONLINE_USER_SESSIONS.isEmpty()) return; Executor executor = pushExecutor; if (executor == null) { ONLINE_USER_SESSIONS.values().forEach(session -> sendMessage(session, payload)); return; } ONLINE_USER_SESSIONS.values().forEach(session -> executor.execute(() -> sendMessage(session, payload))); } /** * 发送消息给 userId_ 前缀的人 */ public static void sendMessagePrefix(String targetId, String message) { String regex = "^" + Pattern.quote(targetId) + "_\\d+$"; Pattern pattern = Pattern.compile(regex); ONLINE_USER_SESSIONS.entrySet().stream().filter(entry -> { Matcher matcher = pattern.matcher(entry.getKey()); return matcher.matches(); }).map(Map.Entry::getValue).forEach(session -> PTZWebSocketUtils.sendMessage(session, message)); } }