欧美成人精品手机在线观看_69视频国产_动漫精品第一页_日韩中文字幕网 - 日本欧美一区二区

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

實時數據推送并非只有WebSocket一種選擇,還有SSE、長輪詢等

admin
2023年10月7日 10:58 本文熱度 649

環境:SpringBoot2.7.16


概述

在Web應用中,有幾種實時數據推送的選擇方案,包括SSE(Server-Sent Events)WebSocket長輪詢等。

SSE是一種基于HTTP協議的服務器向客戶端推送數據的技術。它的優點是實現簡單、輕量級,對現有服務器軟件兼容性好。但是,由于SSE是單向通信模型,只能由服務器向客戶端推送數據,對于需要客戶端向服務器發送數據的場景,SSE就無法滿足需求。

WebSocket是一種雙向通信模型,允許客戶端和服務器之間互相發送消息。它的優點是實時性強、延遲低,但是需要服務器端支持對應的協議棧,實現起來相對復雜一些。

長輪詢是對短輪詢的一種改進版本,通過在盡可能減少對服務器資源浪費的同時,保證消息的相對實時性。長輪詢在客戶端發起請求時,服務器會保持連接打開,等待一定時間后再返回響應。這樣可以減少客戶端頻繁的請求,節省帶寬和服務器資源。但是,如果服務器沒有新的消息產生,客戶端會一直等待響應,實時性就會受到一定影響。

根據實際應用場景和需求,可以選擇適合的實時數據推送方案。如果只需要服務器向客戶端推送數據,且對實時性要求不是特別高,可以選擇SSE。如果需要客戶端向服務器發送數據,或者對實時性要求較高,可以選擇WebSocket或長輪詢。當然,也可以根據實際情況將這幾種方案結合起來使用,以滿足不同的需求。

SSE與WebSocket對比

SSE(Server-Sent Events)和WebSocket都是用于實現實時通信的技術,存在關鍵差異。

通信模型:SSE是單向通信模型,只能由服務器向客戶端推送數據。而WebSocket是雙向通信模型,客戶端和服務器可以互相發送消息。

連接性:SSE使用長輪詢或HTTP流技術,需要頻繁地發起HTTP請求來獲取數據。而 WebSocket只需在握手階段建立一次連接,然后保持連接打開,減少了頻繁建立連接的開銷。

實時性:WebSocket提供了更低的延遲和更高的實時性,因為它支持雙向通信,可以立即將數據推送給客戶端。SSE雖然也可以實現實時性,但由于其單向通信模型,需要服務器定期發送數據。

協議特性:SSE是部署在HTTP協議之上的,現有的服務器軟件都支持。而WebSocket是一個新的協議,需要服務器端支持對應的協議棧。

復雜性:SSE相對WebSocket來說更輕量級,實現更簡單。WebSocket協議較復雜,實現相對困難一些。

總體來說,SSE和WebSocket都有各自的優點和適用場景。SSE輕量級且對現有服務器軟件兼容性好,而WebSocket則提供了更強的雙向通信能力和更高的實時性。

SSE簡介

SSE(Server-Sent Events)是一種用于實現服務器向客戶端實時推送數據的Web技術。與傳統的輪詢和長輪詢相比,SSE提供了更高效和實時的數據推送機制。

SSE基于HTTP協議,允許服務器將數據以事件流(Event Stream)的形式發送給客戶端。客戶端通過建立持久的HTTP連接,并監聽事件流,可以實時接收服務器推送的數據。

SSE的主要特點包括:

簡單易用:SSE使用基于文本的數據格式,如純文本、JSON等,使得數據的發送和解析都相對簡單。

單向通信:SSE支持服務器向客戶端的單向通信,服務器可以主動推送數據給客戶端。

實時性:SSE建立長時間的連接,使得服務器可以實時地將數據推送給客戶端,而無需客戶端頻繁地發起請求。

服務端開發

依賴管理

<dependency>

  <groupId>org.springframework.boot</groupId>

  <artifactId>spring-boot-starter-web</artifactId>

</dependency>

<dependency>

  <groupId>org.springframework.boot</groupId>

  <artifactId>spring-boot-starter-thymeleaf</artifactId>

</dependency>

配置文件

spring:

  mvc:

    static-path-pattern: /**

  web:

resources:

  #靜態文件目錄index.html

      static-locations: classpath:/templates/

接口開發

@RestController@RequestMapping("/sse")public class SseController {   // 該集合用來管理所有客戶端的連接  private final Map<String, SseEmitter> sse = new ConcurrentHashMap<>() ;
 // 創建連接接口,同時指定了消息類型為text/event-stream  @GetMapping(path="/events/{id}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)  public SseEmitter createConnect(@PathVariable("id") String id) throws IOException {    SseEmitter emitter = new SseEmitter(0L);    // 每一個客戶端保存到Map中    sse.put(id, emitter) ;    // 當發生錯誤的回調    emitter.onError(ex -> {      System.err.printf("userId: %s, error: %s%n", id, ex.getMessage()) ;      sse.remove(id) ;    }) ;   // 異步請求完成后的回調    emitter.onCompletion(() -> {      sse.remove(id) ;      System.out.printf("%s, 請求完成...") ;    }) ;    // 異步請求超時回調    emitter.onTimeout(() -> {      System.err.println("超時...") ;    }) ;    return emitter;  }  // 該接口用來進行消息的發送  // 由客戶端發起請求,然后根據id獲取相應的SseEmitter進行消息的發送  @GetMapping("/sender/{id}")  public String sender(@PathVariable("id") String id) throws Exception {    SseEmitter emitter = this.sse.get(id) ;    if (emitter != null) {      try {        emitter.send( "隨機消息 - " + new Random().nextInt(10000000)) ;      } catch (Exception e) {        System.err.println("%s%n", e.getMessage()) ;      }    }    return "success" ;  }}

前端開發

前端比較簡單就是一個index.html頁面

<html>

<head>

  <title>SSE</title>

</head>

<body>

  <button type="button" onclick="closeSse()">Close</button>

  <hr style="margin: 2px; padding: 0px 0px;"/>

  <ul id="list"></ul>

</body>

<script>

  const evtSource = new EventSource(`/sse/events/${Date.now()}`) ;

  evtSource.onmessage = (event) => {

    const newElement = document.createElement("li") ;

    const eventList = document.getElementById("list") ;

    newElement.innerHTML = "接收到消息: " + event.data ;

    eventList.appendChild(newElement) ;

  };

  evtSource.onopen = (event) => {

console.log('建立連接...')

};

  evtSource.onerror = (event) => {

    console.error("發生錯誤:", event) ;

  };

  function closeSse() {

    evtSource.close() ;

  }

</script>

</html>

以上就是前后端的開發,代碼非常的簡單;也就簡單的實現了由服務端實時數據推送。

EventSource對象的readyState有3個狀態值:

0 — connecting

1 — open

2 — closed

測試

調用消息發送接口


自定義事件類型

修改消息發送接口

@GetMapping("/sender/{id}")

public String sender(@PathVariable("id") String id) throws Exception {

    SseEmitter emitter = this.sse.get(id) ;

if (emitter != null)

{

      SseEventBuilder builder = SseEmitter.event() ;

      // 指定事件類型

      builder.name("chat") ;

      String msg = "隨機消息 - " + new Random().nextInt(10000000);

      builder.data(msg) ;

      try {

        emitter.send(builder) ;

      } catch (Exception e) {

        e.printStackTrace();

      }

    }

    return "success" ;

}

前端監聽具體事件類型消息

// 監聽指定事件類型消息evtSource.addEventListener("chat", (event) => {  const newElement = document.createElement("li");  const eventList = document.getElementById("list");
 newElement.innerHTML = "chat message: " + event.data;  eventList.appendChild(newElement);});

注意:默認是“message”事件,因為它可以捕獲沒有 event 字段的事件, * 以及具有特定類型 `event:message` 的事件。* 它不會觸發任何其他類型的事件。

完畢!!!


該文章在 2023/10/7 10:58:31 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業的專業生產管理軟件系統,系統成熟度和易用性得到了國內大量中小企業的青睞。
點晴PMS碼頭管理系統主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業務管理,結合碼頭的業務特點,圍繞調度、堆場作業而開發的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業的高效ERP管理信息系統。
點晴WMS倉儲管理系統提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統,標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協同辦公管理系統。
Copyright 2010-2025 ClickSun All Rights Reserved