欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

利用Vue3?+?SpringBoot打造高效Web實時消息推送系統(tǒng)

 更新時間:2025年11月04日 09:24:50   作者:為java加瓦  
在Vue中實現(xiàn)消息推送,可以通過集成WebSocket服務(wù)來實現(xiàn)實時通信,這篇文章主要介紹了利用Vue3?+?SpringBoot打造高效Web實時消息推送系統(tǒng)的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

好的,作為一名經(jīng)歷過無數(shù)項目實戰(zhàn)的Java全棧工程師,今天我想和你深入聊聊WebSocket——這個在現(xiàn)代Web應(yīng)用中幾乎不可或缺的實時通信技術(shù)。我會通過一個真實的“訂單實時通知”項目,帶你從理論到實踐,再到大廠級別的優(yōu)化,徹底搞懂它。

從“不停打電話”到“拉起微信群”:通信模式的演進

想象一下這個場景:你在等一份重要的外賣,但不知道騎手到哪里了。傳統(tǒng)的方式(HTTP輪詢)就像你每隔30秒給騎手打一次電話:“到了嗎?”“沒呢。”“到了嗎?”“還在路上。”…… 效率低下,且令人煩躁。

這就是輪詢(Polling)的困境:

  • 資源浪費:大量請求在無數(shù)據(jù)更新時被白白消耗,服務(wù)器和網(wǎng)絡(luò)帶寬承受不必要的壓力。

  • 延遲高:數(shù)據(jù)更新的時機,取決于下一次請求何時發(fā)出,存在天然的延遲。

而WebSocket,則像是你和騎手建立了一個實時對講頻道。一旦連接建立,雙方可以隨時主動發(fā)送消息。騎手可以主動告訴你:“已取餐”、“到小區(qū)門口了”、“電梯上樓中”。這才是真正的高效實時通信。

哪些場景必須用它?想想這些:

  • 實時聊天系統(tǒng)(微信、釘釘):消息必須即發(fā)即收。

  • 金融交易看板(股票、加密貨幣):價格變動需在毫秒級內(nèi)推送到所有客戶端。

  • 在線協(xié)作文檔(騰訊文檔、飛書文檔):你敲一個字,協(xié)作者立即能看到。

  • 運維監(jiān)控大盤:服務(wù)器指標(biāo)實時刷新,故障時立即告警。

實戰(zhàn):構(gòu)建一個訂單實時通知系統(tǒng)

理論說再多,不如一行代碼。我們來搭建一個核心架構(gòu):Spring Boot 2.x后端 + Vue3前端,實現(xiàn)新訂單的實時推送。

一、后端(Spring Boot):建立消息中樞

首先,引入核心依賴,Spring Boot已經(jīng)為我們封裝好了一切。

xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

核心配置:打通WebSocket通道

這里的配置決定了客戶端如何連接,以及消息如何路由。

java

@Configuration
@EnableWebSocketMessageBroker // 開啟WebSocket消息代理
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        // 客戶端將通過這個URL來連接WebSocket端點
        registry.addEndpoint("/ws-notification")
                .setAllowedOriginPatterns("*") // 注意:生產(chǎn)環(huán)境應(yīng)指定具體域名
                .withSockJS(); // 啟用SockJS后備選項,增強兼容性
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        // 啟用一個簡單的基于內(nèi)存的消息代理,負(fù)責(zé)向客戶端推送消息
        registry.enableSimpleBroker("/topic"); // 客戶端訂閱以/topic開頭的地址
        // 定義應(yīng)用自身的目的地前綴,客戶端發(fā)送消息到服務(wù)端時使用
        registry.setApplicationDestinationPrefixes("/app");
    }
}

業(yè)務(wù)服務(wù):精準(zhǔn)推送消息

配置好通道,下一步就是如何發(fā)送消息了。

java

@Service
public class NotificationService {

    @Autowired
    private SimpMessagingTemplate messagingTemplate; // Spring提供的消息發(fā)送模板

    /**
     * 廣播新訂單給所有訂閱的客戶端(例如大屏監(jiān)控)
     */
    public void broadcastNewOrder(String orderNumber) {
        // 將消息發(fā)送到 /topic/new-orders,所有訂閱了該目的地的客戶端都會收到
        messagingTemplate.convertAndSend("/topic/new-orders", "新訂單: " + orderNumber);
    }

    /**
     * 私信特定用戶(例如客服端)
     */
    public void notifyUser(String userId, String message) {
        // 發(fā)送到用戶專屬的隊列,Spring會自動將其路由為 /user/{userId}/topic/notification
        messagingTemplate.convertAndSendToUser(userId, "/topic/notification", message);
    }
}

在Controller中,當(dāng)有新訂單創(chuàng)建時,只需注入NotificationService并調(diào)用broadcastNewOrder方法即可。

二、前端(Vue3):建立連接并監(jiān)聽消息

前端需要使用STOMP客戶端庫來與后端通信。

bash

npm install sockjs-client stompjs

封裝WebSocket工具類

為了更好的可維護性和用戶體驗(如斷線重連),我們將其封裝成獨立模塊。

javascript

// utils/websocket.js
import SockJS from 'sockjs-client';
import Stomp from 'stompjs';

let stompClient = null;
let reconnectTimer = null;
const RETRY_INTERVAL = 5000; // 重連間隔5秒

/**
 * 連接WebSocket
 * @param {string} topic 訂閱的消息主題
 * @param {Function} onMessageCallback 收到消息時的回調(diào)函數(shù)
 * @param {Function} refreshCallback 連接成功后的回調(diào)(如刷新列表)
 */
export function connectWebSocket(topic, onMessageCallback, refreshCallback) {
  const socket = new SockJS(import.meta.env.VITE_WS_ENDPOINT || 'http://localhost:8080/ws-notification');
  stompClient = Stomp.over(socket);

  stompClient.connect({},
    // 連接成功回調(diào)
    () => {
      console.log('WebSocket連接成功');
      if (reconnectTimer) clearTimeout(reconnectTimer);

      // 訂閱指定的主題
      stompClient.subscribe(`/topic/${topic}`, (message) => {
        onMessageCallback(message.body);
        refreshCallback?.(); // 可選:收到消息后觸發(fā)數(shù)據(jù)刷新
      });

      refreshCallback?.(); // 連接成功時也刷新一次數(shù)據(jù)
    },
    // 連接失敗回調(diào)
    (error) => {
      console.error('WebSocket連接失敗,嘗試重連...', error);
      scheduleReconnect(topic, onMessageCallback, refreshCallback);
    }
  );
}

// 安排定時重連
function scheduleReconnect(topic, onMessageCallback, refreshCallback) {
  if (reconnectTimer) clearTimeout(reconnectTimer);
  reconnectTimer = setTimeout(() => {
    connectWebSocket(topic, onMessageCallback, refreshCallback);
  }, RETRY_INTERVAL);
}

// 斷開連接
export function disconnectWebSocket() {
  if (stompClient) {
    stompClient.disconnect();
    console.log('WebSocket連接已斷開');
  }
  if (reconnectTimer) clearTimeout(reconnectTimer);
}

在Vue組件中使用

vue

<script setup>
import { onMounted, onBeforeUnmount, ref } from 'vue';
import { ElNotification } from 'element-plus'; // 使用Element Plus的提示組件
import { connectWebSocket, disconnectWebSocket } from '@/utils/websocket';

const orderList = ref([]);

// 收到新訂單通知后的處理
const showNewOrderNotification = (message) => {
  ElNotification({
    title: '?? 新訂單提醒',
    type: 'success',
    message: message,
    duration: 0, // 不自動關(guān)閉,重要訂單提醒
  });
  // 可以在這里播放提示音
};

// 刷新訂單列表數(shù)據(jù)
const refreshOrderList = () => {
  // 這里調(diào)用你的API來獲取最新訂單列表
  console.log('刷新訂單列表數(shù)據(jù)...');
  // fetchOrders().then(data => orderList.value = data);
};

onMounted(() => {
  // 組件掛載時,連接WebSocket并訂閱"new-orders"主題
  connectWebSocket('new-orders', showNewOrderNotification, refreshOrderList);
});

onBeforeUnmount(() => {
  // 組件銷毀前,斷開連接,清理資源
  disconnectWebSocket();
});
</script>

<template>
  <div>
    <!-- 你的訂單列表UI -->
    <div v-for="order in orderList" :key="order.id">
      {{ order.number }}
    </div>
  </div>
</template>

三、大廠級別的優(yōu)化:從“能用”到“好用”

上面的代碼已經(jīng)可以跑了,但要上生產(chǎn)環(huán)境,還必須解決以下幾個問題:

1. 部署上線:Nginx反向代理配置

前端直接連接后端地址在開發(fā)時沒問題,但生產(chǎn)環(huán)境通常需要通過Nginx。

nginx

server {
    listen 80;
    server_name yourdomain.com;

    location / {
        # 代理你的Vue應(yīng)用靜態(tài)資源
        root /usr/share/nginx/html;
        try_files $uri $uri/ /index.html;
    }

    location /ws-notification {
        proxy_pass http://backend-server:8080; # 你的Spring Boot應(yīng)用地址
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade; # 關(guān)鍵:升級協(xié)議頭
        proxy_set_header Connection "Upgrade"; # 關(guān)鍵:連接升級
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_read_timeout 3600s; # WebSocket連接超時時間設(shè)置長一些
    }

    # 其他API請求也代理到后端
    location /api/ {
        proxy_pass http://backend-server:8080;
    }
}

2. 安全第一:WebSocket連接鑒權(quán)

絕不能允許任何人隨便連接你的WebSocket服務(wù)。

服務(wù)端攔截器:

java

@Component
public class AuthChannelInterceptor implements ChannelInterceptor {

    @Override
    public Message<?> preSend(Message<?> message, MessageChannel channel) {
        StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
        
        // 攔截CONNECT命令,進行身份驗證
        if (StompCommand.CONNECT.equals(accessor.getCommand())) {
            // 從Header中獲取Token
            List<String> authHeaders = accessor.getNativeHeader("Authorization");
            String token = (authHeaders != null && !authHeaders.isEmpty()) ? authHeaders.get(0) : null;

            if (token == null || !TokenUtil.verify(token)) {
                throw new IllegalArgumentException("未經(jīng)授權(quán)的連接請求");
            }

            // 驗證通過,將用戶信息存入會話,后續(xù)可通過@MessageMapping方法中的Principal參數(shù)獲取
            String username = TokenUtil.extractUsername(token);
            accessor.setUser(new UsernamePasswordAuthenticationToken(username, null, new ArrayList<>()));
        }
        return message;
    }
}

WebSocketConfig中注冊這個攔截器:

java

@Override
public void configureClientInboundChannel(ChannelRegistration registration) {
    registration.interceptors(new AuthChannelInterceptor());
}

前端連接時攜帶Token:

javascript

// 在連接時,將登錄后獲取的Token放入Header
stompClient.connect(
  { 
    Authorization: `Bearer ${getToken()}` // 例如: "Bearer eyJhbGciOiJIUzI1NiIsInR5..."
  }, 
  // ... 其他回調(diào)不變
);

總結(jié):我們構(gòu)建了一個怎樣的系統(tǒng)?

通過這一套組合拳,我們不再僅僅是一個“Demo”,而是打造了一個產(chǎn)品級的實時推送體系:

  • 架構(gòu)清晰:前后端完全解耦,基于WebSocket + STOMP協(xié)議通信,標(biāo)準(zhǔn)且高效。

  • 性能卓越:摒棄了低效的輪詢,消息秒級可達,服務(wù)器壓力大大降低。

  • 安全可靠:集成了鑒權(quán)機制,與現(xiàn)有登錄體系無縫融合,防止未授權(quán)訪問。

  • 體驗流暢:具備自動斷線重連能力,網(wǎng)絡(luò)波動時能自我恢復(fù),用戶無感知。

  • 生產(chǎn)就緒:通過Nginx代理,解決了跨域、負(fù)載均衡等部署問題。

在實際業(yè)務(wù)中,你可能還會遇到更多深層次問題,比如分布式環(huán)境下Session共享(需引入Redis等外部消息代理替代enableSimpleBroker)、消息可靠性保證(防止推送丟失)、海量連接下的性能調(diào)優(yōu)等。但掌握了以上核心架構(gòu)與思想,你就已經(jīng)拿到了進入實時Web應(yīng)用開發(fā)大門的鑰匙。希望這篇來自實戰(zhàn)的經(jīng)驗總結(jié),能對你的下一個項目有所啟發(fā)。

到此這篇關(guān)于利用Vue3 + SpringBoot打造高效Web實時消息推送系統(tǒng)的文章就介紹到這了,更多相關(guān)Vue3 SpringBoot高效Web實時消息推送系統(tǒng)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue計算屬性computed的使用方法示例

    vue計算屬性computed的使用方法示例

    這篇文章主要介紹了vue計算屬性computed的使用方法,結(jié)合實例形式分析了vue計算屬性computed的基本用法及相關(guān)操作注意事項,需要的朋友可以參考下
    2019-03-03
  • vue動態(tài)刪除從數(shù)據(jù)庫倒入列表的某一條方法

    vue動態(tài)刪除從數(shù)據(jù)庫倒入列表的某一條方法

    今天小編就為大家分享一篇vue動態(tài)刪除從數(shù)據(jù)庫倒入列表的某一條方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • vue-cli腳手架-bulid下的配置文件

    vue-cli腳手架-bulid下的配置文件

    這篇文章主要介紹了vue-cli腳手架-bulid下的配置文件,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • Vue分頁效果與購物車功能

    Vue分頁效果與購物車功能

    這篇文章主要介紹了Vue分頁效果與購物車功能,本文圖文實例相結(jié)合給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-12-12
  • vue3+ts+axios+pinia實現(xiàn)無感刷新方式

    vue3+ts+axios+pinia實現(xiàn)無感刷新方式

    這篇文章主要介紹了vue3+ts+axios+pinia實現(xiàn)無感刷新方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • 一文了解Vue中的nextTick

    一文了解Vue中的nextTick

    Vue中的 nextTick 涉及到Vue中DOM的異步更新,感覺很有意思,特意了解了一下。其中關(guān)于 nextTick 的源碼涉及到不少知識,很多不太理解,暫且根據(jù)自己的一些感悟介紹下 nextTick
    2019-05-05
  • vue中v-model和響應(yīng)式的實現(xiàn)原理解析

    vue中v-model和響應(yīng)式的實現(xiàn)原理解析

    這篇文章主要介紹了vue中v-model和響應(yīng)式的實現(xiàn)原理,通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • Vue3的路由守衛(wèi)以及登錄狀態(tài)儲存過程

    Vue3的路由守衛(wèi)以及登錄狀態(tài)儲存過程

    這篇文章主要介紹了Vue3的路由守衛(wèi)以及登錄狀態(tài)儲存過程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • 如何封裝Vue Element的table表格組件

    如何封裝Vue Element的table表格組件

    這篇文章主要介紹了如何封裝Vue Element的table表格組件,幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下
    2021-02-02
  • Vue中的element tabs點擊錨點定位,鼠標(biāo)滾動定位

    Vue中的element tabs點擊錨點定位,鼠標(biāo)滾動定位

    這篇文章主要介紹了Vue中的element tabs點擊錨點定位,鼠標(biāo)滾動定位方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07

最新評論