package com.care.bigscreen.websocket; import cn.hutool.json.JSONUtil; import com.care.common.vo.UserLogindConvertVO; import com.care.util.ExUtil; import com.care.util.JsonUtil; import com.care.util.JwtUtils; import com.care.util.Result; import io.jsonwebtoken.Claims; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import javax.websocket.*; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.util.concurrent.CopyOnWriteArraySet; /** * Swagger2配置 * * @author stw * @version 1.0.0 创建于 2021/5/24 **/ @ServerEndpoint("/bms/bigscreen/ws") @Component public class BigScreenWebSocketEndpoint { private static final Logger logger = LoggerFactory.getLogger(BigScreenWebSocketEndpoint.class); @Autowired JwtUtils jwtUtils; //用来存放每个客户端对应的BigScreenWebSocketEndpoint对象 private static CopyOnWriteArraySet currentWebSocketSession = new CopyOnWriteArraySet<>(); // 与某个客户端的连接会话,需要通过它来与客户端进行数据收发 private Session session; //用于关联当前客户端和websocket会话的关系 //电话作为登陆用户名 private String phone; //服务站ID private String stationId; /** * websocket 连接打开操作 * * @param session websocket会话对象 */ @OnOpen public void webSocketOnOpen(Session session) { try { //校验参数 String requestParamString = session.getQueryString(); if (StringUtils.isEmpty(requestParamString)) { closeSession(session, "-1", "连接失败,token为空"); return; } //建立websocket和登录用户、站点ID的关联关系 //从token中解析出登录用户的信息 String[] keyValues = requestParamString.split("&"); //取出token 字符串 String ts = null; for (String t : keyValues) { if (t.startsWith("token=")) { ts = t.replaceAll("token=", ""); } else if (t.startsWith("stationId=")) { stationId = t.replaceAll("stationId=", ""); } } if (StringUtils.isEmpty(ts) || StringUtils.isEmpty(stationId)) { closeSession(session, "-1", "连接失败,token或stationId为空"); return; } Claims claims = jwtUtils.tokenParse(ts); if (claims != null) { UserLogindConvertVO vo = JSONUtil.toBean(claims.getSubject(), UserLogindConvertVO.class); if (vo != null) { this.phone = vo.getPhone(); } else{ closeSession(session, "-1", "连接失败,token解析失败"); return; } } logger.info("websocket会话建立:服务站ID={},登录用户={}登录!", this.stationId,this.phone); this.session = session; currentWebSocketSession.add(this); } catch (Exception e) { closeSession(session, "-1", "连接失败,token为空"); logger.error("websocket会话建立异常:"+ ExUtil.exToDetail(e)); } } @OnClose public void onClose(Session session) { //移除连接 currentWebSocketSession.remove(this); logger.info("客户端断开连接,客户端id={},服务站ID={},登录用户={},退出websocket连接", session.getId(), this.stationId, this.phone); } @OnError public void onError(Session session, Throwable error) { logger.error("客户端id={},服务站ID={},登录用户={},连接异常信息={}.", session.getId(), this.stationId, this.phone, error.getCause()); } @OnMessage public void onMessage(String message, Session session) throws Exception { // logger.info("Receive a message from client: " + message); // 页面传过来的消息不做任何处理 logger.info("收到来自" + session.getId() + "的消息" + message); //返回消息给Web Socket客户端(浏览器) // sendMessage(message); } public static void sendMessage(String message) throws IOException { for (BigScreenWebSocketEndpoint endpoint : currentWebSocketSession) { Session session = endpoint.getSession(); if (session.isOpen()) { //发送消息 try { session.getBasicRemote().sendText(message); } catch (IOException e) { logger.info("给服务站ID={},登录用户={} 发送数据失败,客户端连接已经断开.", endpoint.getStationId(), endpoint.getPhone()); } } } } /** * 给客户端发送消息的方法 * * @param stationId 服务站ID * @param msg 发送的信息 */ public static void sendMsgToFront(String stationId,String msg) { //根据服务站ID,匹配连接并发送消息 for (BigScreenWebSocketEndpoint endpoint : currentWebSocketSession) { Session session = endpoint.getSession(); if (session.isOpen() && stationId.equals(endpoint.getStationId())) { //发送消息 try { session.getBasicRemote().sendText(msg); } catch (IOException e) { logger.info("给服务站ID={},登录用户={} 发送数据失败,客户端连接已经断开.", endpoint.getStationId(), endpoint.getPhone()); } } } } /** * 关闭session操作 * * @param session * @param msg * @throws Exception */ private void closeSession(Session session, String code, String msg) { try { if (session != null){ if("-1".equals(code)){ session.getBasicRemote().sendText(JsonUtil.toJson(Result.error(msg))); } else { session.getBasicRemote().sendText(JsonUtil.toJson(Result.success(msg))); } session.close(); } } catch (Exception e) { logger.info("关闭连接异常", e.getCause()); } } public Session getSession() { return session; } public String getPhone() { return phone; } public String getStationId() { return stationId; } }