spring-boot-websocket總結(jié)回顧

前言
websocket的內(nèi)容比我預(yù)期的要少,本來打算分三次分享,但是經(jīng)過昨天和前天的分享,核心內(nèi)容已經(jīng)完結(jié)了,所以我們今天來做一個簡單小結(jié)。
websocket總結(jié)回顧
相比于我們前兩天剛分享的security,websocket確實比較少,不過它內(nèi)容雖然不多,但是這項技術(shù)卻很有用,比如你要搭建一個個人聊天系統(tǒng)或者做一個客服組件,那websocket就是最佳選擇,而且兼容性方便也是沒得說,根據(jù)我的實際測試IE11本身是支持websocket,如果老一點的IE,我們也可以通過STOMP來兼容。
今天我們的核心內(nèi)容也是從一張腦圖開始,公眾號后臺回復(fù)【sping-websocket】獲取腦圖源文件:

核心依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
核心配置
創(chuàng)建一個服務(wù)節(jié)點池,本質(zhì)上它就是一個節(jié)點容器
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
節(jié)點服務(wù)
@ServerEndpoint
需要指定節(jié)點地址,客戶端根據(jù)節(jié)點地址與服務(wù)端通信
@ServerEndpoint("/ws")
@Service
public class WebSocketService {
...
}
監(jiān)聽方法
@OnOpen:客戶端建立連接時會調(diào)用該方法@OnOpen
public void onOpen(Session session) {
String name = nameMap.get(session.getUserPrincipal().getName());
this.session = session;
webSocketServiceSet.add(this);
addOnlineCount();
logger.info("有新連接加入!當前在線人數(shù)為: {}", onlineCount.get());
webSocketServiceSet.parallelStream().forEach(item -> {
try {
sendMessage(item.getSession(), String.format("%s加入群聊!", name));
} catch (Exception e) {
logger.error("發(fā)送消息異常:", e);
}
});
}Session參數(shù)
@OnMessage:客戶端發(fā)送消息時調(diào)用該方法@OnMessage
public void onMessage(String message, Session session) {
logger.info("來自客戶端的消息:{}", message);
webSocketServiceSet.parallelStream().forEach(item -> {
String name = nameMap.get(session.getUserPrincipal().getName());
logger.info("{}發(fā)送了一條消息:{}", name, message);
try {
item.sendMessage(item.getSession(), String.format("%s:%s", name, message));
} catch (IOException e) {
e.printStackTrace();
}
});
}messageSession參數(shù)
@OnClose:客戶端關(guān)閉websocket連接時回調(diào)該方法@OnClose
public void onClose(Session session) {
logger.info("{}退出群聊!", session.getUserPrincipal().getName());
webSocketServiceSet.remove(this);
subOnlineCount();
}Session參數(shù)
@OnError:客戶端發(fā)生錯誤時調(diào)用該方法@OnError
public void onError(Session session, Throwable t) {
logger.error("發(fā)生錯誤:", t);
}SessionThrowable參數(shù)
前端
創(chuàng)建websocket對象
var websocket = new WebSocket("ws://localhost:8989/ws")
指定回調(diào)函數(shù)
openwebsocket.onopen = function () {
// 方法實現(xiàn)
}errorwebsocket.onerror = function () {
// 方法實現(xiàn)
}messagewebsocket.message = function () {
// 方法實現(xiàn)
}closewebsocket.onclose = function () {
// 方法實現(xiàn)
}
發(fā)送消息
websocket.send(message)
STOMP兼容
對于不支持websocket的瀏覽器,我們需要通過stomp協(xié)議進行兼容,但是目前我接觸到的瀏覽器包括IE都是支持websocket的。
配置類
注解
@EnableWebSocketMessageBroker作用:啟用
websocketMessageBroker配置方法
指定客戶端訂閱路徑前綴
registry.enableSimpleBroker("/sub", "/queue")指定服務(wù)端點請求前綴
registry.setApplicationDestinationPrefixes("/request")注冊節(jié)點
registry.addEndpoint("/socket").withSockJS()registerStompEndpoints()configureMessageBroker():
接口
發(fā)送廣播消息
@MessageMapping("/send")
@SendTo("/sub/chat")
public String sendMessage(String value) {
logger.info("發(fā)送消息內(nèi)容:{}", value);
return value;
}發(fā)送私有消息
@MessageMapping("/sendToUser")
public void sendToUser(Principal principal, String body) {
String srcUser = principal.getName();
String[] args = body.split(": ");
String desUser = args[0];
String message = String.format("【%s】給你發(fā)來消息:%s", webSocketService.getNameMap().get(srcUser), args[1]);
// 發(fā)送到用戶和監(jiān)聽地址
simpMessagingTemplate.convertAndSendToUser(desUser, "/queue/customer", message);
}
前端
引入js包
stomp.jssockjs.js建立
STOMP連接創(chuàng)建
SockJS實例var socket = new SockJS('/socket');創(chuàng)建
stompClientvar stompClient = Stomp.over(socket);建立連接
stompClient.connect({}, function (frame) {
// 建立連接后的回調(diào)
setConnected(true);
})斷開
stomp連接stompClient.disconnect()發(fā)送消息
stompClient.send("/request/send", {}, message)接收方訂閱消息
stompClient.connect({}, function () {
console.log("notice socket connected !");
// 訂閱消息地址
stompClient.subscribe('/sub/chat', function (data) {
$('#receive').html(data.body);
});
});
總結(jié)
websocket的內(nèi)容相對比較簡單,而且配置也不復(fù)雜,所以今天也沒有太多要補充說明的,各位小伙伴如果對于之前的知識點還有疑問,可以再回顧下:


