websocket+sockjs公告通知【基於STOMP協議】
阿新 • • 發佈:2021-02-02
前言:
訊息推送技術,之前你可能用過 Ajax 輪詢。輪詢是在特定的的時間間隔(如每1秒),由瀏覽器對伺服器發出HTTP請求,然後由伺服器返回最新的資料給客戶端的瀏覽器。這種傳統的模式帶來很明顯的缺點,即瀏覽器需要不斷的向伺服器發出請求,然而HTTP請求可能包含較長的頭部,其中真正有效的資料可能只是很小的一部分,顯然這樣會浪費很多的頻寬等資源。有了長連線的websocket,能更好的節省伺服器資源和頻寬,並且能夠更實時地進行通訊。
WebSocket 是 HTML5 開始提供的一種在單個 TCP 連線上進行全雙工通訊的協議。
WebSocket 使得客戶端和伺服器之間的資料交換變得更加簡單,允許服務端主動向客戶端推送資料。在 WebSocket API 中,瀏覽器和伺服器只需要完成一次握手,兩者之間就直接可以建立永續性的連線,並進行雙向資料傳輸。
依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
webSocket的配置檔案
@Configuration /** * 註解開啟使用STOMP協議來傳輸基於代理(message broker)的訊息 */ @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { /*@Resource private GetHeaderParamInterceptor getHeaderParamInterceptor;*/ /** * 註冊stomp的端點 */ @Override public void registerStompEndpoints(StompEndpointRegistry registry) { // 允許使用socketJs方式訪問,允許跨域 // 在網頁上我們就可以通過這個連結 // http://localhost:8080//ws/endpointChat // 來和伺服器的WebSocket連線 registry.addEndpoint("/ws/endpointChat") .setAllowedOrigins("*") .withSockJS(); } @Override /** * 配置訊息代理 */ public void configureMessageBroker(MessageBrokerRegistry registry) { //點對點queue,廣播式topic registry.enableSimpleBroker("/queue","/topic"); //registry.setUserDestinationPrefix("/user"); } /** * @Description 採用自定義攔截器 獲取connect時候傳遞的引數 * @Author mk * @Date 2020/12/17 9:47 * @Param * @Return * */ /* @Override public void configureClientInboundChannel(ChannelRegistration registration) { registration.interceptors(getHeaderParamInterceptor); }*/ }
websocket處理類controller
@Controller
public class WsController {
@MessageMapping("/ws/nf")
@SendTo("/topic/nf")
public String handleNF() {
return "公告通知";
}
}
前端程式碼
const actions = { connect(context){ context.state.stomp = Stomp.over(new SockJS("http://39.104.74.107:9090/ws/endpointChat")); context.state.stomp.connect({}, frame=> { //公告 context.state.stomp.subscribe("/topic/nf", message=> { context.commit('toggleNFDot', true); }); }, failedMsg=> { }); } } const mutations = { toggleNFDot(state, newValue){ state.nfDot = newValue; }, }
使用者傳送系統通知,在系統通知儲存到資料庫後,傳送websocket訊息
sendNFMsg(){
this.dialogLoading = true;
var _this = this;
SendMsg({message: this.message, title: this.title}).then(resp=> {
_this.dialogLoading = false;
if (resp && resp.status == 200) {
var data = resp.data;
_this.$message({type: "success", message: resp.data.msg});
if (resp.data.code == 2000000) {
_this.$store.state.stomp.send("/ws/nf", {}, '');
_this.initSysMsgs();
_this.cancelSend();
}
}
})
},
使用者進入home頁面,發起後端請求,看是否有未讀訊息,來控制鬧鐘小紅點的顯示
initSysMsgs(){
var _this = this;
getMsg().then(resp=> {
_this.sysmsgs=resp.data.data;
var isDot = false;
resp.data.data.forEach(msg=> {
if (msg.state == 0) {
isDot = true;
}
})
_this.$store.commit('toggleNFDot', isDot);
})
}
效果圖:
參考自“江南一點雨”大神的vhr專案