package com.supervision.controller; import cn.hutool.core.util.ObjectUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import javax.websocket.*; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.security.Principal; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; @Component @Slf4j @ServerEndpoint("/webSocket/{uid}") public class WebSocketServer { //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。 private static final AtomicInteger onlineNum = new AtomicInteger(0); //concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketServer对象。 private static final ConcurrentHashMap SESSION_POOL = new ConcurrentHashMap<>(); /** * 有客户端连接成功 */ @OnOpen public void onOpen(Session session, @PathParam(value = "uid") String uid) { SESSION_POOL.put(uid, session); onlineNum.incrementAndGet(); log.info(uid + "加入webSocket!当前人数为" + onlineNum); } /** * 连接关闭调用的方法 */ @OnClose public void onClose(Session session, @PathParam(value = "uid") String uid) { SESSION_POOL.remove(uid); int cnt = onlineNum.decrementAndGet(); log.info("有连接关闭,当前连接数为:{}", cnt); } /** * 发送消息 */ public void sendMessage(Session session, String message) throws IOException { if (session != null) { synchronized (session) { session.getBasicRemote().sendText(message); } } } /** * 群发消息 */ public void broadCastInfo(String message) throws IOException { for (Session session : SESSION_POOL.values()) { if (session.isOpen()) { sendMessage(session, message); } } } /** * 发生错误 */ @OnError public void onError(Session session, Throwable throwable) { log.error("发生错误"); throwable.printStackTrace(); } // 实现一个方法用于踢下线用户 public void kickUser(String userId) throws IOException { log.info("踢用户{}下线", userId); Session session = SESSION_POOL.get(userId); if (ObjectUtil.isNotEmpty(session)) { session.close(new CloseReason(CloseReason.CloseCodes.NORMAL_CLOSURE, "用户被踢下线")); } } }