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

使用Java和SpringBoot實現(xiàn)服務(wù)器發(fā)送事件(Server-Sent Events)

 更新時間:2024年02月06日 09:07:40   作者:基督山伯爵_Neo  
使用Java開發(fā)web應(yīng)用,大多數(shù)時候我們提供的接口返回數(shù)據(jù)都是一次性完整返回,有些時候,我們也需要提供流式接口持續(xù)寫出數(shù)據(jù),以下提供一種簡單的方式,本文給大家介紹了如何在Java web中實現(xiàn)服務(wù)器發(fā)送事件,需要的朋友可以參考下

引言

使用Java開發(fā)web應(yīng)用,大多數(shù)時候我們提供的接口返回數(shù)據(jù)都是一次性完整返回。有些時候,我們也需要提供流式接口持續(xù)寫出數(shù)據(jù),以下提供一種簡單的方式。

SSE(Server-Sent Events)

SSE 是一種允許服務(wù)器單向發(fā)送事件到客戶端的技術(shù),它基于HTTP協(xié)議,服務(wù)器可以推送消息到客戶端,但客戶端不能向服務(wù)器發(fā)送消息。

實現(xiàn)

直接上代碼

@RestController
public class TestController {

    private static final Logger logger = LoggerFactory.getLogger(TestController.class);

    @GetMapping("/test")
    public void test(HttpServletResponse response) {
        response.setContentType("text/event-stream");
        response.setCharacterEncoding("utf-8");

        try (final PrintWriter writer = response.getWriter()) {
            // 要推送的內(nèi)容
            final String content = "你好,我的朋友,快過年了,提前祝你新年快樂!";
            int len = content.length();
            int endIndex = 0;
            // 每隔2個字符推送一次,模擬打字機效果
            while (endIndex < len) {
                endIndex = Math.min(endIndex + 2, len);
                final String subContent = content.substring(0, endIndex);
                // 將要推送的內(nèi)容封裝成JSON格式,模擬實際開發(fā)中的數(shù)據(jù)格式,非必須
                final JSONObject json = new JSONObject();
                json.put("data", subContent);
                json.put("code", HttpStatus.OK.value());
                // 最后一次推送時,type為finish,表示推送結(jié)束,其它情況為add
                final String type = endIndex == len
                        ? "finish"
                        : "add";
                json.put("type", type);
                // 組裝成SSE格式的數(shù)據(jù),發(fā)送給前端,這個格式(data: content\n\n)是固定的,content是自定義的推送內(nèi)容
                writer.write("data: " + json.toJSONString() + "\n\n");
                writer.flush();
                // 稍微給點停頓,防止數(shù)據(jù)發(fā)送太快,瀏覽器接收不過來
                TimeUnit.MILLISECONDS.sleep(100);
            }
        } catch (Exception e) {
            Thread.currentThread().interrupt();
            logger.error("流式推送數(shù)據(jù)異常", e);
        }
    }
}

組裝數(shù)據(jù),格式固定為"data: " + content + "\n\n",這里的數(shù)據(jù)格式是服務(wù)器發(fā)送事件(Server-Sent Events,SSE)的標(biāo)準(zhǔn)格式。

SSE 中,數(shù)據(jù)必須以 "data: " 開頭,然后是要發(fā)送的數(shù)據(jù),最后是兩個換行符"\n\n"。這是SSE的規(guī)定格式,客戶端會根據(jù)這種格式來解析服務(wù)器發(fā)送的事件。

接口調(diào)試

用接口調(diào)試工具(我用的是Apifox)調(diào)試接口如下:

接口符合SSE規(guī)范,所以可以被正常識別為事件流推送。

SSE與其他實時通信技術(shù)的比較

SSE與WebSocket的比較

  • 通信方式:SSE是單向的,只能由服務(wù)器向客戶端發(fā)送數(shù)據(jù);而WebSocket是雙向的,服務(wù)器和客戶端都可以發(fā)送數(shù)據(jù)。
  • 協(xié)議:SSE基于HTTP協(xié)議,更易于設(shè)置和配置;WebSocket是一個獨立的協(xié)議。
  • 數(shù)據(jù)格式:SSE發(fā)送的數(shù)據(jù)格式固定,必須是"text/event-stream";而WebSocket可以發(fā)送任何類型的數(shù)據(jù)。
  • 連接:SSE在斷開連接后可以自動重新連接,而WebSocket需要手動處理重連。
  • 瀏覽器支持:WebSocket的瀏覽器支持更廣泛,幾乎所有現(xiàn)代瀏覽器都支持WebSocket;而SSE在某些舊版本的瀏覽器(如IE)中不被支持。

SSE與長輪詢的比較

  • 效率:SSE更高效,因為它只需要一個HTTP連接,就可以持續(xù)地發(fā)送數(shù)據(jù);而長輪詢需要不斷地建立和斷開HTTP連接。
  • 實時性:SSE的實時性更強,因為服務(wù)器可以隨時發(fā)送數(shù)據(jù);而長輪詢需要客戶端不斷地發(fā)送請求來獲取新數(shù)據(jù)。
  • 復(fù)雜性:SSE的實現(xiàn)相對簡單,只需要服務(wù)器按照規(guī)定的格式發(fā)送數(shù)據(jù)即可;而長輪詢的實現(xiàn)較復(fù)雜,需要處理連接的建立和斷開,以及錯誤和超時等問題。
  • 瀏覽器支持:與WebSocket相比,SSE和長輪詢的瀏覽器支持都較差,但長輪詢在更多的瀏覽器中被支持。
  • 適用場景:SSE適用于服務(wù)器需要主動推送數(shù)據(jù)的場景;而長輪詢適用于客戶端需要定期獲取新數(shù)據(jù),但服務(wù)器不需要主動推送數(shù)據(jù)的場景。

注意事項

  • 以上一個簡單的事件流推送接口就實現(xiàn)好了,但是它的問題是客戶端沒法干預(yù)服務(wù)器的推流,如果需要中途停止接收內(nèi)容,基于以上接口是沒法做到的。所以實際項目開發(fā)過程中,可以使用Spring框架提供的SseEmitter
  • ?????瀏覽器支持:并非所有瀏覽器都支持SSE,例如,舊版本的Internet Explorer就不支持SSE。在使用SSE時,需要確保目標(biāo)用戶的瀏覽器支持這項技術(shù)。
  • 連接限制:由于SSE需要保持長連接,因此可能會占用大量的服務(wù)器資源。在使用SSE時,需要考慮到這一點,并根據(jù)實際情況進行優(yōu)化。

以上就是使用Java和SpringBoot實現(xiàn)服務(wù)器發(fā)送事件(Server-Sent Events)的詳細內(nèi)容,更多關(guān)于Java SpringBoot服務(wù)器發(fā)送事件的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論