WebSocket 是基於 TCP 的一種新的網路協議。全雙工通訊,就是隻需要建立一次握手,即可瀏覽器和伺服器雙向資料傳輸
HTTP協議和WebSocket協議對比:
HTTP是短連線
WebSocket是長連線
HTTP通訊是單向的,基於請求響應模式
WebSocket支援雙向通訊
HTTP和WebSocket底層都是TCP連線
String json = JSON.toJSONString(map);
即可將map轉化為json字串
然後呼叫websocket中的方法sendToAllClient(json)
即可傳送到前端,推送訊息
應用場景:彈幕,網頁聊天視窗、體育實況更新、股票基金報價實時更新
個人理解:非同步不重新整理
匯入依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
WebSocketServer類
這跟controller很像,都是透過路徑匹配
package com.sky.websocket;
import org.springframework.stereotype.Component;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
* WebSocket服務
*/
@Component
@ServerEndpoint("/ws/{sid}")
public class WebSocketServer {
//存放會話物件
private static Map<String, Session> sessionMap = new HashMap();
/**
* 連線建立成功呼叫的方法
*/
@OnOpen
public void onOpen(Session session, @PathParam("sid") String sid) {
System.out.println("客戶端:" + sid + "建立連線");
sessionMap.put(sid, session);
}
/**
* 收到客戶端訊息後呼叫的方法
*
* @param message 客戶端傳送過來的訊息
*/
@OnMessage
public void onMessage(String message, @PathParam("sid") String sid) {
System.out.println("收到來自客戶端:" + sid + "的資訊:" + message);
}
/**
* 連線關閉呼叫的方法
*
* @param sid
*/
@OnClose
public void onClose(@PathParam("sid") String sid) {
System.out.println("連線斷開:" + sid);
sessionMap.remove(sid);
}
/**
* 群發
*
* @param message
*/
public void sendToAllClient(String message) {
Collection<Session> sessions = sessionMap.values();
for (Session session : sessions) {
try {
//伺服器向客戶端傳送訊息
session.getBasicRemote().sendText(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
WebSocketconfig
package com.sky.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* WebSocket配置類,用於註冊WebSocket的Bean
*/
@Configuration
public class WebSocketConfiguration {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
為了測試效果,又定義了一個定時任務類來測試這個WebSocket
package com.sky.task;
import com.sky.websocket.WebSocketServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@Component
public class WebSocketTask {
@Autowired
private WebSocketServer webSocketServer;
/**
* 透過WebSocket每隔5秒向客戶端傳送訊息
*/
@Scheduled(cron = "0/5 * * * * ?")
public void sendMessageToClient() {
webSocketServer.sendToAllClient("這是來自服務端的訊息:" + DateTimeFormatter.ofPattern("HH:mm:ss").format(LocalDateTime.now()));
}
}