目錄
什么是webSocket?
webSocket可以用來做什么?
WebSocket操作類
一:測試客戶端向服務端推送消息
1.啟動SpringBoot項目
2.打開網(wǎng)站
3.進行測試消息推送
4.后端進行查看測試結(jié)果
二:測試服務端向客戶端推送消息
1.接口代碼
2.使用postman進行調(diào)用
3.查看測試結(jié)果
什么是webSocket?
????????WebSocket是一種在單個TCP連接上進行全雙工通信的協(xié)議。WebSocket使得客戶端和服務器之間的數(shù)據(jù)交換變得更加簡單,允許服務端主動向客戶端推送數(shù)據(jù)。而Http請求只能從客戶端請求服務端才能得到響應。在WebSocket API中,瀏覽器和服務器只需要完成一次握手,兩者之間就直接可以創(chuàng)建持久性的連接,并進行雙向數(shù)據(jù)傳輸。
webSocket可以用來做什么?
????????利用雙向數(shù)據(jù)傳輸?shù)奶攸c可以用來完成很多功能,不需要前端輪詢,浪費資源。例如:
聊天功能、數(shù)據(jù)實時更新和視頻彈幕等
webSocket協(xié)議
本協(xié)議有兩部分:握手和數(shù)據(jù)傳輸。
握手是基于http協(xié)議的。
來自客戶端的握手看起來像如下形式:
GET ws://localhost/chat HTTP/1.1
Host: localhost
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key:dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Protocol: chat,superchat
Sec-WebSocket-Version: 13
來自服務器的握手看起來像如下形式
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept:s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
SpringBoot快速整合WebSocket代碼案例:
下面我就使用SpringBoot快速整合WebSocket實現(xiàn)服務端與客戶端的相互推送消息;
代碼層級結(jié)構(gòu)
maven依賴
<!--WebSocket的依賴-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
WebSocket配置類
package com.example.springboot_websocket_demo01;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig {
/**
* 注入ServerEndpointExporter,
* 這個bean會自動注冊使用了@ServerEndpoint注解聲明的Websocket endpoint
*/
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
WebSocket操作類
通過該類WebSocket可以進行群推送以及單點推送
package com.example.springboot_websocket_demo01;
import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
@Component
@Slf4j
@ServerEndpoint("/websocket/{userId}") // 接口路徑 ws://localhost:8087/webSocket/userId;
public class WebSocket {
//與某個客戶端的連接會話,需要通過它來給客戶端發(fā)送數(shù)據(jù)
private Session session;
/**
* 用戶ID
*/
private String userId;
//concurrent包的線程安全Set,用來存放每個客戶端對應的MyWebSocket對象。
//雖然@Component默認是單例模式的,但springboot還是會為每個websocket連接初始化一個bean,所以可以用一個靜態(tài)set保存起來。
// 注:底下WebSocket是當前類名
private static CopyOnWriteArraySet<WebSocket> webSockets = new CopyOnWriteArraySet<>();
// 用來存在線連接用戶信息
private static ConcurrentHashMap<String, Session> sessionPool = new ConcurrentHashMap<String, Session>();
/**
* 鏈接成功調(diào)用的方法
*/
@OnOpen
public void onOpen(Session session, @PathParam(value = "userId") String userId) {
try {
this.session = session;
this.userId = userId;
webSockets.add(this);
sessionPool.put(userId, session);
log.info("【websocket消息】有新的連接,總數(shù)為:" + webSockets.size());
} catch (Exception e) {
}
}
/**
* 鏈接關閉調(diào)用的方法
*/
@OnClose
public void onClose() {
try {
webSockets.remove(this);
sessionPool.remove(this.userId);
log.info("【websocket消息】連接斷開,總數(shù)為:" + webSockets.size());
} catch (Exception e) {
}
}
/**
* 收到客戶端消息后調(diào)用的方法
*
* @param message
*/
@OnMessage
public void onMessage(String message) {
log.info("【websocket消息】收到客戶端消息:" + message);
}
/**
* 發(fā)送錯誤時的處理
*
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
log.error("用戶錯誤,原因:" + error.getMessage());
error.printStackTrace();
}
// 此為廣播消息
public void sendAllMessage(String message) {
log.info("【websocket消息】廣播消息:" + message);
for (WebSocket webSocket : webSockets) {
try {
if (webSocket.session.isOpen()) {
webSocket.session.getAsyncRemote().sendText(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 此為單點消息
public void sendOneMessage(String userId, String message) {
Session session = sessionPool.get(userId);
if (session != null && session.isOpen()) {
try {
log.info("【websocket消息】 單點消息:" + message);
session.getAsyncRemote().sendText(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 此為單點消息(多人)
public void sendMoreMessage(String[] userIds, String message) {
for (String userId : userIds) {
Session session = sessionPool.get(userId);
if (session != null && session.isOpen()) {
try {
log.info("【websocket消息】 單點消息:" + message);
session.getAsyncRemote().sendText(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
注意:WebSocketConfig和WebSocket必須放在同一層級下,否則Websocket掃描不到ServerEndpoint注解。
一:測試客戶端向服務端推送消息
1.啟動SpringBoot項目
2.打開網(wǎng)站
WebSocket測試 devTest.run
輸入
ws://127.0.0.1:8080/websocket/100
進行連接,測試是否連接成功
3.進行測試消息推送
4.后端進行查看測試結(jié)果
測試成功,說明客戶端可以使用WebSocket對服務端推送消息。
二:測試服務端向客戶端推送消息
1.接口代碼
package com.example.springboot_websocket_demo01;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
public class YourController {
@Autowired
private WebSocket webSocket;
@PostMapping("/sendNotification")
public void sendNotification() {
try {
// 創(chuàng)建業(yè)務消息信息
String message = "postman調(diào)用接口訪問后端服務器存儲數(shù)據(jù)并使用websocket將消息推送給前端客戶端";
// 全體發(fā)送
webSocket.sendAllMessage(message);
// 單個用戶發(fā)送 (userId為用戶id)
String userId = "1";
String message1 = "【websocket消息】 單點消息:只發(fā)送給id為"+userId+"的用戶。";
webSocket.sendOneMessage(userId, message1);
// 多個用戶發(fā)送 (userIds為多個用戶id,逗號‘,’分隔)
String[] userIds = {"1", "2"};
String message2 = "【websocket消息】 單點消息:只發(fā)送給id為"+userIds.toString()+"的用戶。";
webSocket.sendMoreMessage(userIds, message2);
} catch (Exception e) {
// 輸出異常信息
e.printStackTrace();
}
}
}
2.使用postman進行調(diào)用
用來模仿客戶端發(fā)送消息到后端服務器然后返回給客戶端。(其實也可以直接在WebSocket類中的onMessage中直接進行操作,調(diào)用sendAllMessage等其他方法進行測試);
3.查看測試結(jié)果
WebSocket測試 devTest.run
正常結(jié)果為
文章來源:http://www.zghlxwxcb.cn/news/detail-808247.html
還有很多測試方法,自己可以去思考,以上對于SpringBoot整合WebSocket來說可以算是一個簡單的入門案例了。文章來源地址http://www.zghlxwxcb.cn/news/detail-808247.html
到了這里,關于【Java】SpringBoot快速整合WebSocket實現(xiàn)客戶端服務端相互推送信息的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!