一、為什么有websocket
主流web應(yīng)用使用的http協(xié)議只能進行單向訪問级及,要想實時通信只能通過輪詢的方式實現(xiàn)颖变,而高頻度的輪詢十分消耗性能,此時就體現(xiàn)了websocket的優(yōu)點
1.支持雙向通信矢否,可以實現(xiàn)服務(wù)端與客戶端的主動收發(fā)消息
2.較少的控制開銷:在連接創(chuàng)建后,服務(wù)器和客戶端之間交換數(shù)據(jù)時脑溢,用于協(xié)議控制的數(shù)據(jù)包頭部相對較小
二僵朗、Websocket簡介
WebSocket 是一種網(wǎng)絡(luò)傳輸協(xié)議,可在單個 TCP 連接上進行全雙工通信屑彻,位于 OSI 模型的應(yīng)用層
websocket應(yīng)用場景:
1.聊天室
2.實時告警
三验庙、Websocket應(yīng)用(Java springboot)
1.引入依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2.創(chuàng)建配置類
@Configuration
//@EnableWebSocketMessageBroker
@EnableWebSocket
public class WSConfig implements WebSocketConfigurer {
@Autowired
private MyWebSocketHandler webSocketHandler;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(webSocketHandler, "/my-websocket").setAllowedOrigins("*");
}
}
這里可以使用@EnableWebSocket(簡單應(yīng)用) 或者 @EnableWebSocketMessageBroker(消息代理功能 通俗的講就是復雜封裝了)
@EnableWebSocketMessageBroker:該配置類中使用@EnableWebSocketMessageBroker注解來啟用WebSocket消息代理功能,使用configureMessageBroker方法來配置消息代理的相關(guān)參數(shù)社牲,使用registerStompEndpoints方法來注冊Stomp協(xié)議的WebSocket端點
3.創(chuàng)建處理類
這里需要使用webSocketSession 進行收發(fā)消息粪薛,而正常在業(yè)務(wù)類中獲取webSocketSession 較為復雜,這里使用封裝好的方法里獲取搏恤,即建立連接時執(zhí)行afterConnectionEstablished方法违寿,在這里保存session让禀,斷開連接執(zhí)行afterConnectionClosed,刪除session
@Component
@Slf4j
public class MyWebSocketHandler extends TextWebSocketHandler{
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
sessions.add(session);
log.info("WebSocket connection established");
}
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
String payload = message.getPayload();
log.info("Received message: " + payload);
// 回復消息給客戶端
try {
session.sendMessage(new TextMessage("Hello, client! You said: " + payload));
} catch (IOException e) {
log.error("Error sending message to session: " + session.getId(), e);
}
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
sessions.remove(session);
log.info("WebSocket connection closed");
}
private static final CopyOnWriteArrayList<WebSocketSession> sessions = new CopyOnWriteArrayList<>();
public void sendMessageToAll(String message) {
// log.info("Sending message to all sessions: {}", message);
for (WebSocketSession session : sessions) {
try {
session.sendMessage(new TextMessage(message));
log.info("Sending message to all sessions: successful");
} catch (IOException e) {
log.error("Error sending message to session {}: {}", session.getId(), e.getMessage());
}
}
}
}
4.實際業(yè)務(wù)類中使用
通過控制臺日志可以查看收發(fā)消息是否成功
@Override
public void run(ApplicationArguments args) throws Exception{
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
while (true){
Thread.sleep(3000);
String time = simpleDateFormat.format(new Date());
webSocketHandler.sendMessageToAll("發(fā)送消息咯 --- " + time);
}
}