<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      長輪詢 實現

      什么是長輪詢(Long Polling)?

      在 常規的 HTTP 請求 中:

      1. 客戶端 發送請求到服務器。
      2. 服務器 處理請求并立即返回響應。
      3. 客戶端 收到響應后,HTTP 連接關閉。

      但如果服務器端數據 更新不頻繁,客戶端需要 不斷發送請求(短輪詢) 來獲取最新數據,這種方式浪費資源,因為大多數請求都是無效的(服務器沒新數據)。

      長輪詢(Long Polling)如何突破 HTTP 一次請求一次響應的限制?

      長輪詢仍然遵循 HTTP 協議的 “一次請求,一次響應”,但關鍵在于服務器不立即返回響應,而是等待數據可用后才返回。

      流程如下:

      1. 客戶端發送 HTTP 請求,請求服務器的最新數據。
      2. 服務器保持該請求(不立即返回),直到:
        • 有新數據時,服務器返回數據并關閉連接。
        • 超時(如 30 秒)時,服務器返回空數據或超時響應,客戶端需重新請求。
      3. 客戶端收到響應后,立即發起新的請求,等待下一次數據更新。

      這樣,服務器 只在有新數據時才返回響應,減少了無效請求,節約資源。

      Spring Boot DeferredResult 實現長輪詢

      Spring Boot 提供了 DeferredResult 來支持長輪詢,它允許服務器 延遲返回 HTTP 響應,直到有數據可用。

      ?? 代碼示例:模擬消息推送
      @RestController
      public class LongPollingController {
          private final Map<String, DeferredResult<String>> requestMap = new ConcurrentHashMap<>();
      
          @GetMapping("/long-polling")
          public DeferredResult<String> longPolling(@RequestParam String clientId) {
              // 創建一個 DeferredResult 對象,超時 30 秒
              DeferredResult<String> deferredResult = new DeferredResult<>(30000L, "No new messages");
      
              // 存儲請求(等待數據到來)
              requestMap.put(clientId, deferredResult);
      
              // 監聽請求超時,超時后移除
              deferredResult.onCompletion(() -> requestMap.remove(clientId));
      
              return deferredResult;
          }
      
          @PostMapping("/send-message")
          public ResponseEntity<String> sendMessage(@RequestParam String clientId, @RequestParam String message) {
              DeferredResult<String> deferredResult = requestMap.get(clientId);
              if (deferredResult != null) {
                  deferredResult.setResult(message); // 立即返回消息
                  requestMap.remove(clientId);
              }
              return ResponseEntity.ok("Message sent");
          }
      }
      

      ?? 代碼解析

      1. 客戶端 調用 /long-polling?clientId=123 發送請求。
      2. 服務器 在 requestMap 里 存儲該請求,并 不立即返回(除非超時)。
      3. 當 /send-message 發送新消息時:
        • 服務器找到該 clientId 的請求,并立即返回消息。
        • 客戶端收到消息后,會再次請求 /long-polling,等待下一條數據。
      4. 如果 30 秒內沒有消息,返回 "No new messages",客戶端需要重新請求。
      ?? 客戶端示例(JavaScript AJAX 輪詢)
      function longPolling() {
          fetch('/long-polling?clientId=123')
              .then(response => response.text())
              .then(data => {
                  console.log("Received:", data);
                  setTimeout(longPolling, 100); // 立即發送新請求,等待下一次數據
              })
              .catch(error => {
                  console.error("Polling error:", error);
                  setTimeout(longPolling, 5000); // 失敗后延遲 5 秒重試
              });
      }
      
      // 啟動長輪詢
      longPolling();
      

      ?? 客戶端不斷請求服務器:

      • 當有 新消息,服務器立即返回數據,客戶端重新請求。
      • 當 超時(30s 內無消息),服務器返回 "No new messages",客戶端也會重新請求。

      ?? 長輪詢 vs. 短輪詢 vs. WebSocket

      方式 機制 適用場景 服務器資源消耗 網絡流量
      短輪詢(Short Polling) 客戶端每隔 X 秒請求一次 低并發,數據更新頻繁 高(大量無效請求)
      長輪詢(Long Polling) 客戶端請求,服務器等數據可用后再返回 中等并發,數據不頻繁更新 低(只有新數據時才返回)
      WebSocket 雙向長連接,實時數據推送 高并發,實時性高(如聊天、游戲) 低(連接保持但不頻繁創建)

      多實例條件下的實現

      • clientId = user1訪問app1的/long-polling接口,等待接口返回數據
      • clientId = user2訪問app2的/send-message接口, 向clientId = user1發送message,

      由于不在同一個實例,無法獲取requestMap并進行setResult(),那么我們需要如下處理:

      • 在步驟1的時候, 往redis中存放key = user1, value=app1的鍵值,
      • 在步驟2的時候,查詢獲取value,然后將message發送到queue = app1的隊列中;
        • 實例app1的監聽queue = app1的,進行setResult()操作;長輪詢接口返回數據給用戶
        • 如果長輪詢不存在,那么需要增加額外機制保存歷史信息,比如存放在db中,每次訪問時,先查詢和加載歷史信息

      ?? 什么時候用長輪詢?

      ? 適用于

      • 即時消息通知(如 Web 版微信消息提醒)。
      • 狀態更新(如訂單狀態變更、設備在線狀態)。
      • 服務器端數據更新不頻繁,但需要及時通知。

      ? 不適用于

      • 高并發、低延遲的實時通信(WebSocket 更合適)。
      • 服務器壓力大時(可以用 Server-Sent Events(SSE))。

      總結

      1. 長輪詢是基于 HTTP 協議,不改變“一次請求,一次響應”的機制。
      2. 服務器不立即響應,而是等待數據可用后才返回,減少無效請求,提高效率。
      3. Spring Boot 的 DeferredResult 可以輕松實現長輪詢。
      4. 適用于低流量的狀態變更通知,不適用于高并發的實時通信(建議 WebSocket)。
      posted @ 2025-03-04 10:57  又是火星人  閱讀(386)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产伦精区二区三区视频| 美女黄网站人色视频免费国产 | 国产在线观看播放av| 激情自拍校园春色中文| 久久人与动人物a级毛片| 亚洲中文字幕一区二区| 精品亚洲欧美无人区乱码| 中文字幕国产在线精品| 亚洲欧美日韩在线码| 无码人妻斩一区二区三区| 国产欧美精品一区二区三区四区 | 欧美精品高清在线观看| 国产一区二区三区导航| 美腿丝袜亚洲综合在线视频| 日韩深夜福利视频在线观看| 久久这里只精品热免费99| 国产精品成人综合色在线| 国产高清小视频一区二区| 男女爽爽无遮挡午夜视频| 韩产日产国产欧产| 亚洲精品一区二区三区不| 亚洲国产欧美一区二区好看电影| 亚洲视频一区| 国产精品爽黄69天堂A| 亚洲AV日韩AV综合在线观看| 久久亚洲精品日本波多野结衣| 国产福利酱国产一区二区| 国产av一区二区三区综合| 亚洲欧美综合精品成人网站| 美女无遮挡免费视频网站| 免费人成自慰网站| 强伦人妻一区二区三区| 青青国产揄拍视频| 中文国产成人精品久久不卡| 国产一区二区三区AV在线无码观看| 亚洲天堂一区二区成人在线| 99久久婷婷国产综合精品青草漫画 | 日本精品网| 交口县| 国内少妇人妻偷人精品视频| 亚洲AV无码国产成人久久强迫|