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

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

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

      websocket是什么以及它要怎么用

      WebSocket 實(shí)時(shí)通知機(jī)制
      在高并發(fā)、異步下單場(chǎng)景中,它是提升用戶體驗(yàn)、降低輪詢壓力的關(guān)鍵組件。
      接下來(lái)會(huì)從原理講清楚,再結(jié)合“秒殺活動(dòng)”落地展示完整的前后端交互與代碼實(shí)現(xiàn)(Java Spring Boot + 前端示例)。


      一、WebSocket 是什么?

      WebSocket 是一種在瀏覽器和服務(wù)器之間建立「全雙工、持久連接」的通信協(xié)議
      與傳統(tǒng) HTTP 不同,HTTP 是短連接、請(qǐng)求響應(yīng)式的;而 WebSocket 建立連接后,服務(wù)器可以主動(dòng)推送消息給客戶端,不需要客戶端輪詢。

      ?? 對(duì)比傳統(tǒng) HTTP 輪詢

      特點(diǎn)HTTP 輪詢WebSocket
      連接模式 短連接,請(qǐng)求-響應(yīng) 持久連接,雙向通信
      服務(wù)器能否主動(dòng)發(fā)消息 ? 不能 ? 可以
      性能 頻繁請(qǐng)求,壓力大 長(zhǎng)連接,輕量、實(shí)時(shí)
      適用場(chǎng)景 請(qǐng)求量小、實(shí)時(shí)性低 聊天、訂單狀態(tài)、秒殺、行情推送

      二、在「秒殺活動(dòng)」中為什么用 WebSocket?

      在你的秒殺設(shè)計(jì)中:

      • 用戶點(diǎn)擊“立即搶購(gòu)” → 系統(tǒng)用 Redis + MQ 異步下單

      • 請(qǐng)求立即返回 "QUEUED" 狀態(tài);

      • 后端在隊(duì)列消費(fèi)者落單后,才知道成功或失敗。

      如果不用 WebSocket:

      • 用戶只能輪詢 GET /seckill/status?messageId=...

      • 并發(fā)量高時(shí),會(huì)造成 Web 層 + Redis + DB 壓力。

      如果用 WebSocket:

      • 用戶請(qǐng)求秒殺后,保持 WebSocket 長(zhǎng)連接;

      • 后端消費(fèi)者落單完成時(shí),通過(guò) WebSocket 通道主動(dòng)推送訂單狀態(tài)變更

      • 用戶即時(shí)看到結(jié)果,不需要反復(fù)刷新。

      ?? 實(shí)時(shí)、節(jié)流、省資源。


      三、WebSocket 在秒殺系統(tǒng)中的使用流程(圖解)

              ┌──────────────────────┐
              │       瀏覽器端        │
              │   1. 建立 WebSocket  │
              │   2. 發(fā)送秒殺請(qǐng)求     │
              │   3. 等待推送結(jié)果     │
              └──────────┬───────────┘
                         │
                WebSocket 連接
                         │
              ┌──────────▼──────────┐
              │   秒殺服務(wù) (Spring)  │
              │ - 維護(hù)連接映射表     │
              │ - 通過(guò) MQ 消費(fèi)結(jié)果   │
              │ - 推送狀態(tài)到客戶端   │
              └──────────┬───────────┘
                         │
                       MQ/Rabbit
                         │
              ┌──────────▼──────────┐
              │     消費(fèi)者服務(wù)       │
              │ - 創(chuàng)建訂單           │
              │ - 發(fā)送結(jié)果通知       │
              └──────────────────────┘

      四、詳細(xì)實(shí)現(xiàn)(Java + 前端)

      ?? 前端實(shí)現(xiàn)(示例)

      假設(shè)前端是一個(gè)簡(jiǎn)單的 Vue / HTML 頁(yè)面。

      <!DOCTYPE html>
      <html>
      <head>
        <title>秒殺活動(dòng)</title>
      </head>
      <body>
        <h2>秒殺活動(dòng)</h2>
        <button id="buyBtn">立即搶購(gòu)</button>
        <div id="status"></div>
      
        <script>
          const userId = "user_123";
          const ws = new WebSocket(`ws://localhost:8080/ws/seckill/${userId}`);
      
          ws.onopen = () => {
            console.log("? WebSocket connected");
          };
      
          ws.onmessage = (event) => {
            const msg = JSON.parse(event.data);
            if (msg.type === "ORDER_STATUS") {
              document.getElementById("status").innerText = "訂單狀態(tài): " + msg.status;
            }
          };
      
          document.getElementById("buyBtn").onclick = async () => {
            const res = await fetch("/api/seckill/buy?eventId=1001&userId=" + userId, {
              method: "POST"
            });
            const data = await res.json();
            document.getElementById("status").innerText = "請(qǐng)求結(jié)果: " + data.status;
          };
        </script>
      </body>
      </html>

      說(shuō)明:

      • 頁(yè)面在加載時(shí)與服務(wù)器建立 WebSocket 長(zhǎng)連接;

      • 當(dāng)用戶點(diǎn)擊“立即搶購(gòu)”后,發(fā)起 HTTP 下單請(qǐng)求;

      • 后端在訂單異步完成后,通過(guò) WebSocket 主動(dòng)推送消息;

      • 前端即時(shí)更新顯示。


      ?? 后端實(shí)現(xiàn)(Spring Boot)

      我們需要三個(gè)部分:

      1. WebSocket 服務(wù)端(負(fù)責(zé)連接與推送)

      2. 秒殺請(qǐng)求 Controller(發(fā)起秒殺邏輯)

      3. 訂單消費(fèi)者(異步落單后推送結(jié)果)


      1?? WebSocket 配置與服務(wù)端類

      // WebSocketConfig.java
      @Configuration
      @EnableWebSocket
      public class WebSocketConfig implements WebSocketConfigurer {
          @Override
          public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
              registry.addHandler(new SeckillWebSocketHandler(), "/ws/seckill/{userId}")
                      .setAllowedOrigins("*"); // 生產(chǎn)環(huán)境記得做白名單
          }
      }
      // SeckillWebSocketHandler.java
      @Component
      public class SeckillWebSocketHandler extends TextWebSocketHandler {
      
          // 存儲(chǔ)所有用戶連接(簡(jiǎn)單實(shí)現(xiàn),可換為 Redis + Channel 分布式映射)
          private static final Map<String, WebSocketSession> userSessions = new ConcurrentHashMap<>();
      
          @Override
          public void afterConnectionEstablished(WebSocketSession session) {
              String userId = getUserId(session);
              userSessions.put(userId, session);
              System.out.println("用戶 " + userId + " 已連接");
          }
      
          @Override
          public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
              String userId = getUserId(session);
              userSessions.remove(userId);
              System.out.println("用戶 " + userId + " 已斷開(kāi)");
          }
      
          private String getUserId(WebSocketSession session) {
              return session.getUri().getPath().split("/ws/seckill/")[1];
          }
      
          public void sendMessageToUser(String userId, String message) {
              WebSocketSession session = userSessions.get(userId);
              if (session != null && session.isOpen()) {
                  try {
                      session.sendMessage(new TextMessage(message));
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
          }
      }

      2?? 秒殺 Controller(異步下單 + 即時(shí)返回) 

      @RestController
      @RequestMapping("/api/seckill")
      public class SeckillController {
      
          @Autowired
          private MessageQueueProducer mqProducer;
          @Autowired
          private SeckillWebSocketHandler wsHandler;
      
          @PostMapping("/buy")
          public ResponseEntity<?> buy(@RequestParam Long eventId, @RequestParam String userId) {
              // 假設(shè) Redis 校驗(yàn)邏輯已經(jīng)通過(guò)
              String messageId = UUID.randomUUID().toString();
              SeckillMessage msg = new SeckillMessage(messageId, eventId, userId);
      
              // 發(fā)送異步消息給 MQ
              mqProducer.send("seckill-topic", msg);
      
              // 立即通知前端:排隊(duì)中
              wsHandler.sendMessageToUser(userId, "{\"type\":\"ORDER_STATUS\", \"status\":\"QUEUEING\"}");
      
              return ResponseEntity.ok(Map.of("status", "QUEUED", "messageId", messageId));
          }
      }

      3?? 消費(fèi)者處理(模擬異步下單完成后推送結(jié)果)

      @Component
      public class SeckillConsumer {
      
          @Autowired
          private SeckillWebSocketHandler wsHandler;
      
          // 模擬從 MQ 消費(fèi)到消息
          @RabbitListener(queues = "seckill-queue")
          public void handleSeckill(SeckillMessage msg) throws Exception {
              System.out.println("消費(fèi)到秒殺消息:" + msg);
              Thread.sleep(2000); // 模擬落單耗時(shí)
      
              // 模擬結(jié)果(成功/失敗)
              boolean success = Math.random() > 0.2;
              String status = success ? "SUCCESS" : "FAILED";
      
              // 通知前端(WebSocket 推送)
              wsHandler.sendMessageToUser(
                  msg.getUserId(),
                  String.format("{\"type\":\"ORDER_STATUS\", \"status\":\"%s\", \"orderNo\":\"%s\"}",
                          status, msg.getMessageId())
              );
          }
      }

      五、WebSocket 在秒殺系統(tǒng)中的優(yōu)勢(shì)

      優(yōu)勢(shì)描述
      ? 實(shí)時(shí)性強(qiáng) MQ 消費(fèi)完成立刻推送結(jié)果給前端
      ? 降低輪詢壓力 不需要前端頻繁 GET /status
      ? 提升體驗(yàn) 用戶感覺(jué)“搶購(gòu)?fù)炅⒖讨澜Y(jié)果”
      ? 可擴(kuò)展 支持多用戶連接、廣播通知等
      ?? 注意 要做斷線重連與分布式會(huì)話管理

      六、生產(chǎn)實(shí)踐中要考慮的問(wèn)題

      問(wèn)題解決方案
      WebSocket 連接量大(百萬(wàn)用戶) Netty / Gateway 分發(fā)層 維護(hù)長(zhǎng)連接(例如 Spring WebFlux 或 IM 服務(wù))
      多實(shí)例部署時(shí)如何路由用戶連接 用 Redis Pub/Sub 或 Kafka 通知其他實(shí)例轉(zhuǎn)發(fā)消息
      用戶斷線怎么辦 前端定時(shí)重連 + 狀態(tài)輪詢兜底
      安全性 WebSocket 握手時(shí)帶 Token 鑒權(quán),不允許匿名連接

      七、總結(jié)

      ? WebSocket 在秒殺系統(tǒng)中的角色:

      “讓用戶在異步下單模型下實(shí)時(shí)獲知訂單狀態(tài),替代高頻輪詢。”

      ? 典型實(shí)現(xiàn)路徑:

      1. 用戶進(jìn)入活動(dòng)頁(yè) → 建立 WebSocket;

      2. 點(diǎn)擊搶購(gòu) → HTTP 調(diào)用 /buy;

      3. 后端 Redis + MQ 異步落單;

      4. 消費(fèi)端完成后 → 通過(guò) WebSocket 主動(dòng)推送結(jié)果;

      5. 前端即時(shí)顯示成功/失敗。

      ? 典型技術(shù)棧:

      • 后端: Spring Boot + WebSocket + MQ (Rabbit/Kafka)

      • 前端: WebSocket API + 狀態(tài) UI 更新

      • 連接管理: Redis Pub/Sub + Session 映射

       

      posted @ 2025-11-02 23:22  Boblim  閱讀(10)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 国产乱人伦偷精品视频下| 精品综合一区二区三区四区| 久久亚洲精品成人av秋霞| 国产黄色免费看| 亚洲欧美日韩国产精品专区| 国内偷自第一区二区三区| 男人的天堂av社区在线| 亚洲欧美日韩精品色xxx| 狠狠色丁香婷婷综合尤物| 国产精品自拍三级在线观看| 高清dvd碟片 生活片| 中文字幕日韩精品人妻| 日本熟妇浓毛| 精品一区二区不卡无码AV| 精品无码久久久久久尤物| 成人一区二区三区久久精品 | 好紧好湿好黄的视频| 肥城市| 国产免费视频一区二区| 亚洲av综合色区在线观看| 性色a∨精品高清在线观看| 国产精品中文第一字幕| 狠狠色综合久久丁香婷婷| 在线播放免费人成毛片| 国产亚洲一二三区精品| 亚洲成av人片无码迅雷下载| 中文字幕无码久久精品| 亚洲精品香蕉一区二区| 中文字幕日韩精品亚洲一区| AV区无码字幕中文色| 亚洲国产精品综合久久20| 在线看国产精品自拍内射| 在线国产你懂的| 四虎国产精品永久在线下载| 中文国产不卡一区二区| 午夜精品一区二区三区在线观看 | 妓院一钑片免看黄大片| 潮喷失禁大喷水av无码| 国产一区二区三区综合视频| 亚洲熟妇在线视频观看| 欧美亚洲h在线一区二区|