package com.care.bms.websocket; import cn.hutool.json.JSONUtil; import com.care.common.util.ExUtil; import com.care.common.util.JsonUtil; import com.care.common.util.JwtUtils; import com.care.common.util.Result; import com.care.common.vo.UserLogindConvertVO; import io.jsonwebtoken.Claims; import io.swagger.annotations.ApiModelProperty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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/order/ws") @Component public class WebSocketEndpoint { private static final Logger logger = LoggerFactory.getLogger(WebSocketEndpoint.class); //用来存放每个客户端对应的BigScreenWebSocketEndpoint对象 private static CopyOnWriteArraySet currentWebSocketSession = new CopyOnWriteArraySet<>(); // 与某个客户端的连接会话,需要通过它来与客户端进行数据收发 private Session session; //用于关联当前客户端和websocket会话的关系 //电话作为登陆用户名 private String phone; @ApiModelProperty("机构ID") private Long orgId; @ApiModelProperty("服务站ID,角色为坐席时,该字段可能未空") private Long 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=", ""); } } if (StringUtils.isEmpty(ts)) { closeSession(session, "-1", "连接失败,token为空"); return; } Claims claims = JwtUtils.tokenParse(ts); if (claims != null) { UserLogindConvertVO vo = JSONUtil.toBean(claims.getSubject(), UserLogindConvertVO.class); if (vo != null) { this.phone = vo.getPhone(); this.orgId = vo.getOrgId(); this.stationId = vo.getStationId(); } else{ closeSession(session, "-1", "连接失败,token解析失败"); return; } } logger.info("websocket会话建立:登录用户={}登录!",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={},登录用户={},退出websocket连接", session.getId(), this.phone); } @OnError public void onError(Session session, Throwable error) { logger.error("客户端id={},登录用户={},连接异常信息={}.", session.getId(), 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(Long orgId,Long stationId ,String message) throws IOException { for (WebSocketEndpoint endpoint : currentWebSocketSession) { Session session = endpoint.getSession(); if (session.isOpen()) { if (endpoint.orgId == orgId){ //发送消息 try { session.getBasicRemote().sendText(message); } catch (IOException e) { logger.info("登录用户={} 发送数据失败,客户端连接已经断开.", 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; } }