WebSocket:說實話,主要目的就是替代長輪詢實現實時消息推送
例如:掃碼登錄、異步下的title消息提示等等
直接上碼:
導入pom依賴
org.springframework.boot spring-boot-starter-websocket 1.3.5.RELEASE
編寫配置類
package com.example.demo.config.websocket; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; /** * @Author: Chang Yu * @Date: 9/27/2019 2:28 PM */ @Configuration public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }
編寫WebSocket
package com.example.demo.config.websocket; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import javax.websocket.*; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.atomic.AtomicInteger; /** * @Author: Chang Yu * @Date: 9/27/2019 2:26 PM */ @ServerEndpoint("/websocket/CalculateNotr") @Component public class MessageNotr { public static Logger log = LoggerFactory.getLogger(MessageNotr.class); private static final AtomicInteger OnlineCount = new AtomicInteger(0); // concurrent包的線程安全Set,用來存放每個客戶端對應的Session對象。 private static CopyOnWriteArraySet SessionSet = new CopyOnWriteArraySet(); @OnOpen public void onOpen(Session session) { SessionSet.add(session); int cnt = OnlineCount.incrementAndGet(); // 在線數加1 log.info("有連接加入,當前連接數為:{}", cnt); // SendMessage(session, "連接成功"); } /** * 連接關閉調用的方法 */ @OnClose public void onClose(Session session) { SessionSet.remove(session); int cnt = OnlineCount.decrementAndGet(); log.info("有連接關閉,當前連接數為:{}", cnt); } /** * 收到客戶端消息後調用的方法 * * @param message 客戶端發送過來的消息 */ @OnMessage public void onMessage(String message, Session session) { log.info("來自客戶端的消息:{}", message); SendMessage(session, "收到消息,消息內容:" + message); } /** * 出現錯誤 * * @param session * @param error */ @OnError public void onError(Session session, Throwable error) { log.error("發生錯誤:{},Session ID: {}", error.getMessage(), session.getId()); error.printStackTrace(); } /** * 發送消息,實踐表明,每次瀏覽器刷新,session會發生變化。 * * @param session * @param message */ public static void SendMessage(Session session, String message) { try { session.getBasicRemote().sendText(message); // session.getBasicRemote().sendText(String.format("%s (From Server,Session ID=%s)", message, session.getId())); } catch (IOException e) { log.error("發送消息出錯:{}", e.getMessage()); e.printStackTrace(); } } /** * 群發消息 * * @param message * @throws IOException */ public static void BroadCastInfo(String message) { try { for (Session session : SessionSet) { if (session.isOpen()) { SendMessage(session, message); } } } catch (Exception e) { log.error("發送消息出錯:{}", e.getMessage()); e.printStackTrace(); } } /** * 指定Session發送消息 * * @param sessionId * @param message * @throws IOException */ public static void SendMessage(String message, String sessionId) { try { Session session = null; for (Session s : SessionSet) { if (s.getId().equals(sessionId)) { session = s; break; } } if (session != null) { SendMessage(session, message); } else { log.warn("沒有找到你指定ID的會話:{}", sessionId); } } catch (Exception e) { log.error("發送消息出錯:{}", e.getMessage()); e.printStackTrace(); } } }
測一波


簡單吧,學會了嗎,對於分佈式下的webSocket,會話可以結合Redis進行共享。
關鍵字: 上碼 artifactId groupId