標籤:WebSocket,Session,Postman。
一、簡介
WebSocket通過一個TCP連接在客戶端和服務器之間建立一個全雙工、雙向的通信通道,使得客戶端和服務器之間的數據交換變得更加簡單,允許服務端主動向客戶端推送數據,在WebSocket的API中,瀏覽器和服務器只需要完成一次握手,兩者之間就直接可以創建持久性的連接,並進行雙向數據傳輸。
【基於Postman工具的WebSocket交互】
Connected to ws://127.0.0.1:8088/web/socket/msg
Handshake Details
Request URL: http://127.0.0.1:8088/web/socket/msg
Request Method: GET
Status Code: 101
Request Headers
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: 5Qrs8JeRLsiY9G/PRJUocQ==
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Host: 127.0.0.1:8088
Response Headers
Upgrade: websocket
Connection: upgrade
Sec-WebSocket-Accept: E3aFw2bBzxByPCynmQ7lZ+7BgsU=
Sec-WebSocket-Extensions: permessage-deflate;client_max_window_bits=15
二、工程搭建
1、工程結構
2、依賴管理
在starter-websocket
的依賴中,涉及到spring
框架中兩個關係較爲密切的組件,分別是websocket
和messaging
組件。
<!--WebSocket-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<version>${spring-boot.version}</version>
</dependency>
三、WebSocket用法
1、示意圖
在下面的案例中,大致模擬這樣一個流程,三個客戶端分別和服務端建立連接,然後進行客戶端之間的會話通信。
2、API參考
這裏通過4個核心的方法註解,分別處理會話的不同動作,比如連接的建立和關閉,通信交互和錯誤處理;在實際的應用場景中,需要在通信方法中設計更多的指令來應對不同的業務場景。
@ServerEndpoint("/web/socket/msg")
public class MsgWebSocket {
private static final ConcurrentHashMap<String,Session> sessions = new ConcurrentHashMap<>();
private static final AtomicInteger onlineCount = new AtomicInteger(0);
/**
* 建立連接調用的方法
*/
@OnOpen
public void onOpen(Session session) {
String userId = session.getRequestParameterMap().get("userId").get(0);
// 加入Set中
sessions.put(userId,session);
// 在線數增加
onlineCount.getAndIncrement();
log.info("session-{},online-count-{}",session.getId(),onlineCount.get());
}
/**
* 客戶端消息處理的方法
*/
@OnMessage
public void sendMsg(Session sender,String message) throws Exception {
MsgDTO dto = JSONUtil.toBean(message, MsgDTO.class);
Session receiver = sessions.get(dto.getUserId());
if (receiver != null) {
receiver.getBasicRemote().sendText(dto.getMsg());
}
}
/**
* 關閉連接調用的方法
*/
@OnClose
public void onClose(Session session) {
String userId = session.getRequestParameterMap().get("userId").get(0);
// 從Set中刪除
sessions.remove(userId);
// 在線數減少
onlineCount.getAndDecrement();
log.info("session-{},down-line-count-{}",session.getId(),onlineCount.get());
}
/**
* 發生錯誤調用的方法
*/
@OnError
public void onError(Session session, Throwable throwable) throws Exception {
log.error("Web Stock Error", throwable);
session.getBasicRemote().sendText(throwable.getMessage());
}
}
測試效果圖:注意這裏使用的是postman最新版本。
四、源碼參考
文檔倉庫:
https://gitee.com/cicadasmile/butte-java-note
源碼倉庫:
https://gitee.com/cicadasmile/butte-spring-parent