import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; /** * websocket推送 * */ @ServerEndpoint("/websocket/{sid}") @Component @Slf4j public class WebSocketServer { private static Logger log = LoggerFactory.getLogger(WebSocketServer.class); //静态变量,用来记录当前在线连接数。 private static int onlineCount = 0; //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。 private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>(); // //心跳保活发送消息 // private static final String HEARTBEAT_MESSAGE = "ping"; // // private ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); // // private AtomicBoolean isAlive = new AtomicBoolean(true); //与某个客户端的连接会话,需要通过它来给客户端发送数据 private Session session; //接收sid private String sid=""; /** * 连接建立成功调用的方法*/ @OnOpen public void onOpen(Session session,@PathParam("sid") String sid) { this.session = session; webSocketSet.add(this); //加入set中 addOnlineCount(); //在线数加1 log.info("有新窗口开始监听:"+sid+",当前在线人数为" + getOnlineCount()); this.sid=sid; try { sendMessage("连接成功"); //发送心跳 // startHeartbeatTask(); } catch (IOException e) { log.error("调用onOpen失败----------websocket IO异常"); } } //心跳保活 // private void startHeartbeatTask() { // scheduler.scheduleAtFixedRate(() -> { // if (isAlive.get() && session.isOpen()) { // try { // sendMessage(HEARTBEAT_MESSAGE); // } catch (IOException e) { // // 处理连接异常,可能需要关闭连接 // isAlive.set(false); // try { // session.close(); // } catch (IOException ex) { // // 记录日志或执行其他清理操作 // } // } // } // }, 0, 5, TimeUnit.SECONDS); // } /** * 连接关闭调用的方法 */ @OnClose public void onClose() { webSocketSet.remove(this); //从set中删除 subOnlineCount(); //在线数减1 log.info("----有一连接关闭!当前在线人数为" + getOnlineCount()); } /** * 收到客户端消息后调用的方法 * * @param message 客户端发送过来的消息*/ @OnMessage public void onMessage(String message, Session session) { log.info("----收到来自窗口"+sid+"的信息 :"+message); //群发消息 for (WebSocketServer item : webSocketSet) { try { item.sendMessage(message); } catch (IOException e) { e.printStackTrace(); log.error("调用onMessage失败----------websocket IO异常"); } } } /** * * @param session * @param error */ @OnError public void onError(Session session, Throwable error) { log.error("发生错误"); error.printStackTrace(); } /** * 实现服务器主动推送 */ public void sendMessage(String message) throws IOException { this.session.getBasicRemote().sendText(message); } /** * 群发自定义消息 * */ public static void sendInfo(String message,@PathParam("sid") String sid) throws IOException { log.info("推送消息到窗口"+sid+",推送内容:"+message); for (WebSocketServer item : webSocketSet) { try { //这里可以设定只推送给这个sid的,为null则全部推送 if(sid==null) { item.sendMessage(message); }else if(item.sid.equals(sid)){ item.sendMessage(message); } } catch (IOException e) { continue; } } } public static synchronized int getOnlineCount() { return onlineCount; } public static synchronized void addOnlineCount() { WebSocketServer.onlineCount++; } public static synchronized void subOnlineCount() { WebSocketServer.onlineCount--; } }
依赖
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.1</version>
<scope>provided</scope>
</dependency>