package com.dy.pipIrrRemote.largeScreen; 
 | 
  
 | 
import com.dy.common.aop.SsoCheck; 
 | 
import com.dy.common.aop.SsoVo; 
 | 
import com.dy.common.springUtil.SpringContextUtil; 
 | 
import lombok.extern.slf4j.Slf4j; 
 | 
import org.springframework.beans.factory.annotation.Autowired; 
 | 
import org.springframework.context.annotation.Scope; 
 | 
import org.springframework.stereotype.Component; 
 | 
  
 | 
import jakarta.websocket.*; 
 | 
import jakarta.websocket.server.PathParam; 
 | 
import jakarta.websocket.server.ServerEndpoint; 
 | 
import java.io.IOException; 
 | 
import java.util.concurrent.ConcurrentHashMap; 
 | 
  
 | 
/** 
 | 
 * @Author: liurunyu 
 | 
 * @Date: 2025/2/10 15:25 
 | 
 * @Description 客户端(浏览器)每建立一个websocket连接,服务端就会创建一个WebSocketServer实例 
 | 
 * 应用前提是存在一个Config类,如本模块的WebSocketConfig,这时@ServerEndpoint受SpringBoot容器 
 | 
 * 管理了(在嵌入式web Servlet环境中) 
 | 
 */ 
 | 
@Slf4j 
 | 
@ServerEndpoint("/websocket/ls/{token}") 
 | 
@Component 
 | 
@Scope("prototype") // 非单例,每次请求都会创建新的实例 
 | 
public class WebSocketServer { 
 | 
  
 | 
    // 静态变量,记录当前在线连接数 
 | 
    private static int onlineCount = 0; 
 | 
  
 | 
    // 存放每个客户端对应的WebSocketServer对象 
 | 
    private static ConcurrentHashMap<String, WebSocketServer> webSocketMap = new ConcurrentHashMap<>(); 
 | 
  
 | 
    // 客户端连接会话,通过它给客户端发送数据 
 | 
    private Session session; 
 | 
  
 | 
    private String orgTag; 
 | 
  
 | 
    // 客户端上线时刻 
 | 
    //private String onLineDt ; 
 | 
    // 客户端 
 | 
    private String token = ""; 
 | 
  
 | 
    @Autowired 
 | 
    private SsoCheck ssoCheck ; 
 | 
  
 | 
    /** 
 | 
     * 连接建立成功调用的方法 
 | 
     * @param session websocket会话对象 
 | 
     * @param token 客户端id 
 | 
     */ 
 | 
    @OnOpen 
 | 
    public void onOpen(Session session, @PathParam("token") String token) { 
 | 
        if(this.token == null || this.token.length() == 0){ 
 | 
            this.session = session; 
 | 
            //this.onLineDt = DateTime.yyyy_MM_dd_HH_mm_ss() ; 
 | 
            this.token = token; 
 | 
            this.sendMessage(WebSocketHeartBeat.getHeartBeatMessage()); 
 | 
  
 | 
            if (webSocketMap.containsKey(token)) { 
 | 
                webSocketMap.remove(token); 
 | 
                webSocketMap.put(token, this); 
 | 
            } else { 
 | 
                webSocketMap.put(token, this); 
 | 
                WebSocketServer.addOnlineCount(); 
 | 
            } 
 | 
            if(this.ssoCheck == null){ 
 | 
                //2025-07-22 不知为什么,this.ssoCheck会为null 
 | 
                this.ssoCheck = SpringContextUtil.getBean(SsoCheck.class); 
 | 
            } 
 | 
            Object rObj = this.ssoCheck.check(token); 
 | 
            if(rObj != null) { 
 | 
                if (rObj instanceof SsoVo ssoVo) { 
 | 
                    this.orgTag = ssoVo.dataSourceName ; 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 连接关闭调用的方法 
 | 
     */ 
 | 
    @OnClose 
 | 
    public void onClose() { 
 | 
        if (webSocketMap.containsKey(token)) { 
 | 
            webSocketMap.remove(token); 
 | 
            //从set中删除 
 | 
            WebSocketServer.subOnlineCount(); 
 | 
        } 
 | 
        log.info("客户端:" + token + ",关闭了websocket"); 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 收到客户端消息后调用的方法 
 | 
     * @param message 客户端发送过来的消息 
 | 
     * @param session 
 | 
     */ 
 | 
    @OnMessage 
 | 
    public void onMessage(String message, Session session) { 
 | 
        log.info("客户端:" + token + ",websocket报文:" + message); 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 会话异常 
 | 
     * @param session 
 | 
     * @param error 
 | 
     */ 
 | 
    @OnError 
 | 
    public void onError(Session session, Throwable error) { 
 | 
        //log.error("客户端:" + this.token + ",websocket会话异常,原因:" + error.getMessage()); 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 服务器主动推送消息 
 | 
     */ 
 | 
    public void sendMessage(String message) { 
 | 
        try{ 
 | 
            this.session.getBasicRemote().sendText(message); 
 | 
        }catch (Exception e){ 
 | 
            log.error("客户端:" + token + ",websocket网络发送数据异常", e); 
 | 
        } 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 服务器主动群推送消息 
 | 
     */ 
 | 
    public static void sendMessage2AllClient(String orgTag, String message) throws IOException { 
 | 
        ConcurrentHashMap.KeySetView<String, WebSocketServer> tokens = webSocketMap.keySet(); 
 | 
        for (String token : tokens) { 
 | 
            WebSocketServer webSocketServer = webSocketMap.get(token); 
 | 
            if(orgTag == null){ 
 | 
                webSocketServer.sendMessage(message); 
 | 
            }else{ 
 | 
                if(webSocketServer.orgTag != null && webSocketServer.orgTag.equals(orgTag)){ 
 | 
                    webSocketServer.sendMessage(message); 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 服务器指定客户端推送消息 
 | 
     */ 
 | 
    public static void sendMessage2OneClient(String message, String token) throws IOException { 
 | 
        if (message != null && message.length() != 0 && webSocketMap.containsKey(token)) { 
 | 
            webSocketMap.get(token).sendMessage(message); 
 | 
        } else { 
 | 
            log.error("客户端" + token + ",不在线!"); 
 | 
        } 
 | 
    } 
 | 
  
 | 
    public static synchronized int getOnlineCount() { 
 | 
        return onlineCount; 
 | 
    } 
 | 
  
 | 
    public static synchronized void addOnlineCount() { 
 | 
        WebSocketServer.onlineCount++; 
 | 
    } 
 | 
  
 | 
    public static synchronized void subOnlineCount() { 
 | 
        WebSocketServer.onlineCount--; 
 | 
    } 
 | 
} 
 |