sse java_SSE詳解

SSE(Server-Sent Events):通俗解釋起來就是一種基于HTTP的,以流的形式由服務端持續向客戶端發送數據的技術

應用場景

由于HTTP是無狀態的傳輸協議,每次請求需由客戶端向服務端建立連接,HTTPS還需要交換秘鑰,所以一次請求,建立連接的過程占了很大比例

在http1.1中(1.0也有但未寫入標準),雖然增加了keep-alive來保持和服務器的長連接,省去了很多建立連接的過程,但通信過程仍然是應答式1:1的方式,也就是想要獲得數據,就必須先發送一個request才能得到一個response,所以在實時監控、推送、視頻直播等實時性較高或者帶寬利用較苛刻的場景,仍然不是很合適

SSE技術由于能保持連接,并持續接收服務端的數據,所以彌補了這一缺點,與其他類似技術方案相比,短輪詢、Coment、WebSocket,在大多數時候,SSE仍然是最好的選擇

各技術方案的優缺點

短輪詢

短輪詢很簡單,即客戶端定時的向服務端發送請求,如果服務端有數據返回,則返回數據,否則返回空數據

優點:實現簡單

缺點:如果想實時性好,則必須輪詢間隔短,但會有大量的請求是無效的(返回空數據),如果輪詢間隔長,則實時性不好,數據到達客戶端的延時最大會趨近于輪詢間隔

Coment:一種HACK技術

以即時通信為代表的web應用程序對數據的Low Latency要求,傳統的基于輪詢的方式已經無法滿足,而且也會帶來不好的用戶體驗。于是一種基于http長連接的“服務器推”技術便被hack出來。這種技術被命名為Comet,這個術語由Dojo Toolkit 的項目主管Alex Russell在博文Comet: Low Latency Data for the Browser首次提出,并沿用下來。

Coment技術有兩種實現,分別是長輪詢(long-polling)和基于 Iframe 及 htmlfile 的流(http streaming)方式

1.長輪詢(long-polling)

瀏覽器發出ajax 請求,服務器端接收到請求后,會阻塞請求直到有數據或者超時才返回,瀏覽器JS在處理請求返回信息(超時或有效數據)后再次發出請求,重新建立連接。在此期間服務器端可能已經有新的數據到達,服務器會選擇把數據保存,直到重新建立連接,瀏覽器會把所有數據一次性取回。

優缺點:這種技術沒有明顯的優缺點,如果非要說,就是需要額外的框架支持吧,且在之前服務端異步編程支持程度并不高的時候,(例如java的servlet3.0之前),后端也需要額外的框架支持

2.基于 Iframe 及 htmlfile 的流

Iframe是html標記,這個標記的src屬性會保持對指定服務器的長連接請求,服務器端則可以不停地返回數據,相對于第一種方式,這種方式跟傳統的服務器推則更接近。

在第一種方式中,瀏覽器在收到數據后會直接調用JS回調函數,但是這種方式該如何響應數據呢?可以通過在返回數據中嵌入JS腳本的方式,如“”,服務器端將返回的數據作為回調函數的參數,瀏覽器在收到數據后就會執行這段JS腳本。

缺點:IE、Morzilla Firefox 下端的進度欄都會顯示加載沒有完成,而且 IE 上方的圖標會不停的轉動,表示加載正在進行。

WebSocket

類似TCP socket,參考WebSocket詳解

優點:雙工通信

缺點:需專門定義數據協議,解析數據流,且部分服務器支持不完善,后臺例如java spring boot 2.1.2 僅支持websocket 1.0(最高已達1.3)

SSE

優點:開發簡單,和傳統的http開發幾乎無任何差別,客戶端開發簡單,有標準支持(EventSource)

缺點:和websocket相比,只能單工通信,建立連接后,只能由服務端發往客戶端,且占用一個連接,如需客戶端向服務端通信,需額外打開一個連接

其他

在基于spring的開發中,可以使用SseEmitter類進行通信

@GetMapping(value = "/watch", produces = MediaType.TEXT_EVENT_STREAM_VALUE)

public synchronized SseEmitter watch(HttpServletRequest request, @RequestParam("point") String point) throws Exception {

final HttpSession session = request.getSession();

//此處超時時間優先級高于servlet容器的request timeout,PS:此超時時間固定,無法通過心跳等其他手段保持連接,超時后 瀏覽器端默認會重新連接,但SeeEmitter無法復用

SseEmitter emitter = new SseEmitter(300 * 1000L);

String key = String.format("watch:%s", point);

WatchConsumer consumer = new WatchConsumer<>(client, emitter, point);

if (this.client.watch(point, consumer)) {

emitter.onCompletion(() -> session.removeAttribute(key));

emitter.onTimeout(() -> session.removeAttribute(key));

emitter.onError(throwable -> {

throwable.printStackTrace();

session.removeAttribute(key);

});

session.setAttribute(key, consumer);

}

return emitter;

}

也可以利用WebFlux,

@GetMapping("/stream-sse")

public Flux> streamEvents() {

return Flux.interval(Duration.ofSeconds(1))

.map(sequence -> ServerSentEvent. builder()

.id(String.valueOf(sequence))

.event("periodic-event")

.data("SSE - " + LocalTime.now().toString())

.build());

}

但相比之下SseEmitter有OnTimeout和OnCompletion等事件,更加靈活

PS:由于瀏覽器對于同一個domain,有并發數限制,例如chrome最大是6,長連接會持續性的占用一個連接,同時會占用一個服務器端的一個連接

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/371176.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/371176.shtml
英文地址,請注明出處:http://en.pswp.cn/news/371176.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

520. Detect Capital

題目&#xff1a; Given a word, you need to judge whether the usage of capitals in it is right or not. We define the usage of capitals in a word to be right when one of the following cases holds: All letters in this word are capitals, like "USA".A…

盒模型的屬性丶display顯示丶浮動

一丶盒模型的屬性(重要) 1.padding padding是標準文檔流,父子之間調整位置 <!DOCTYPE html><html><head><meta charset"UTF-8"><title>padding</title><style>*{padding: 0;margin: 0;}.box{width: 200px;height: 200px;b…

MapReduce:通過數據密集型文本處理

自上次發布以來已經有一段時間了&#xff0c;因為我一直在忙于Coursera提供的一些課程。 有一些非常有趣的產品&#xff0c;值得一看。 前一段時間&#xff0c;我購買了Jimmy Lin和Chris Dyer的MapReduce數據密集型處理程序 。 本書以偽代碼格式介紹了幾種關鍵的MapReduce算法。…

ubuntu(deepin)安裝apache2并支持php7.0

linux虛擬機下用于開發環境測試&#xff0c;安裝的apache和php7.0&#xff0c;但是簡單安裝完兩者后apache并不能解析php&#xff0c;原因是確實apache的php擴展。 # 首先安裝apache sudo apt-get install apache2 # 然后安裝php7.0 sudo apt-get install php7.0 # 一般執行完這…

java applet 換行_Java復習題

一、選擇題1.有Java語句如下&#xff0c;則說法正確的是()A.此語句是錯誤的B. a.length的值為5C. b.length的值為5D. a.length和b.length的值都為52.整數除法中&#xff0c;如果除數為0&#xff0c;則將導致的異常是( B )A. NullPointerExceptionB. ArithmeticExceptionC. Arra…

解決:MVC對象轉json包含\r \n

項目中對象轉json字符串時&#xff0c;如下&#xff1a;JsonSerializerSettings jsetting new JsonSerializerSettings(); jsetting.DefaultValueHandling DefaultValueHandling.Ignore; return JsonConvert.SerializeObject(resultMoldels, Formatting.Indented, jsetting);…

CSS 小結筆記之滑動門技術

所謂的滑動門技術&#xff0c;就是指盒子背景能夠自動拉伸以適應不同長度的文本。即當文字增多時&#xff0c;背景看起來也會變長。 大多數應用于導航欄之中&#xff0c;如微信導航欄: 具體實現方法如下&#xff1a; 1、首先每一塊文本內容是由a標簽與span標簽組成 <a hr…

使用API??身份驗證的Spring Security

背景 盡管有許多博客文章詳細介紹了如何使用Spring Security&#xff0c;但是當問題域位于標準LDAP或數據庫身份驗證之外時&#xff0c;我仍然經常發現配置挑戰。 在本文中&#xff0c;我將介紹一些針對Spring Security的簡單自定義&#xff0c;使其能夠與基于REST的API調用一起…

java nlpir_4-NLPIR漢語分詞系統-JAVA

好吧&#xff0c;之前用的是舊版的&#xff0c;現在出了個新版的&#xff0c;優先選擇用新版的哈。從官網下載相應的開發包&#xff0c;然后主要需要找到這幾個東西添加到項目工程里面&#xff0c;1.Data文件夾 2.NLPIR_JNI.DLL 3.NLPIR.jar 4.nlpir.properties添加完那些東西后…

淺析C語言中assert的用法(轉)

原文地址&#xff1a;http://www.jb51.net/article/39685.htm 以下是對C語言中assert的使用方法進行了介紹&#xff0c;需要的朋友可以參考下。 assert宏的原型定義在<assert.h>中&#xff0c;其作用是如果它的條件返回錯誤&#xff0c;則終止程序執行&#xff0c;原型定…

hihocoder offer收割編程練習賽12 D 尋找最大值

思路&#xff1a; 可能數據太水了&#xff0c;隨便亂搞就過了。 實現&#xff1a; 1 #include <iostream>2 #include <cstdio>3 #include <algorithm>4 using namespace std;5 typedef long long ll;6 7 int a[100005], n;8 9 int main() 10 { 11 int t;…

vue error:The template root requires exactly one element.

error:[vue/valid-template-root] The template root requires exactly one element. 原因&#xff1a; 因為vue的模版中只有能一個根節點&#xff0c;所以在<template>中插入第二個元素就會報錯 解決方案&#xff1a; 將<template>中的元素先用一個<div>…

測試驅動陷阱,第2部分

單元測試中單元的故事 在本文的上半部分 &#xff0c;您可能會看到一些不好但很流行的測試示例。 但是我不是一個專業評論家&#xff08;也被稱為“巨魔”或“仇恨者”&#xff09;&#xff0c;沒有任何建設性的話就抱怨。 多年的TDD教給我的不僅僅是事情會變得多么糟糕。 有許…

java 代碼 設置環境變量_Java 配置環境變量教程

【聲明】歡迎轉載&#xff0c;但請保留文章原始出處→_→【正文】1、安裝JDK開發環境開始安裝JDK&#xff1a;修改安裝目錄如下&#xff1a;確定之后&#xff0c;單擊“下一步”。注&#xff1a;當提示安裝JRE時&#xff0c;可以選擇不要安裝。2、配置環境變量&#xff1a;對于…

組合數據類型練習,英文詞頻統計實例上(2017.9.22)

字典實例&#xff1a;建立學生學號成績字典&#xff0c;做增刪改查遍歷操作。 sno[33號,34號,35號,36號] grade[100,90,80,120] d{33號:100,34號:90,35號:80,36號:120} print(d) print(每個學號對應分數:,d.items()) print(彈出35號的分數:,d.pop(35號)) print(獲取學號:,d.key…

java 代碼中設置 臨時 環境變量

System.setProperty("hadoop.home.dir", "D:\\software\\software_install\\dev_install\\hadoop-2.4.1"); 轉載于:https://www.cnblogs.com/zychengzhiit1/p/6662376.html

什么是快速開發框架

什么是快速開發框架 前言 做為一個程序員&#xff0c;在開發的過程中會發現&#xff0c;有框架同無框架&#xff0c;做起事來是完全不同的概念&#xff0c;關系到開發的效率、程序的健壯、性能、團隊協作、后續功能維護、擴展......等方方面面的事情。很多朋友在學習搭建自己…

java中的math.abs_Java.math.BigDecimal.abs()方法

全屏Java.math.BigDecimal.abs()方法java.math.BigDecimal.abs()返回一個BigDecimal&#xff0c;其值是此BigDecimal的絕對值&#xff0c;其標度是this.scale()。聲明以下是java.math.BigDecimal.abs()方法的聲明public BigDecimal abs()參數NA返回值此方法返回的名為value&…

我需要多少內存

什么是保留堆&#xff1f; 我需要多少內存&#xff1f; 在構建解決方案&#xff0c;創建數據結構或選擇算法時&#xff0c;您可能會問自己&#xff08;或其他人&#xff09;這個問題。 如果此圖包含1,000,000條邊并且我使用HashMap進行存儲&#xff0c;此圖是否適合我的3G堆&am…

C語言程序設計預報作業

1閱讀鄒欣老師的博客--師生關系,針對文中的幾種師生關系談談你的看法&#xff0c;你期望的師生關系是什么樣的&#xff1f; 答&#xff1a;我認為文中的師生關系都存在一些缺陷&#xff0c;第一種師生關系是建立在病態關系上的&#xff0c;學生不是植物自然有自己的思想。所以我…