国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

服務器推送事件:一種從服務器流式推送事件的簡易方法

開發 服務器
今天我要繼續著手實現服務器推送事件,因為昨天一整天我都沉浸在上述這些錯誤里。好在我學到了一個以前從未聽說過的易學易用的網絡技術,心里還是很高興的。

哈嘍!昨天我見識到了一種我以前從沒見過的從服務器推送事件的炫酷方法:服務器推送事件server-sent events!如果你只需要讓服務器發送事件,相較于 Websockets,它們或許是一個更簡便的選擇。

我會聊一聊它們的用途、運作原理,以及我昨日在試著運行它們的過程中遇到的幾個錯誤。

問題:從服務器流式推送更新

現在,我有一個啟動虛擬機的 Web 服務,客戶端輪詢服務器,直到虛擬機啟動。但我并不想使用輪詢方式。

相反,我想讓服務器流式推送更新。我跟 Kamal 說我要用 Websockets 來實現它,而他建議使用服務器推送事件不失為一個更簡便的選擇!

我登時就愣住了——那什么玩意???聽起來像是些我從來沒見過的稀罕玩意兒。于是乎我就查了查。

服務器推送事件就是個 HTTP 請求協議

下文便是服務器推送事件的運作流程。我-很-高-興-地了解到它們就是個 HTTP 請求協議。

1.客戶端提出一個 GET 請求(舉個例子)https://yoursite.com/events 2.客戶端設置 Connection: keep-alive,這樣我們就能有一個長連接 3.服務器設置設置一個 Content-Type: text/event-stream 響應頭 4.服務器開始推送事件,就比如下文這樣:

event: status
data: one

舉個例子,這里是當我借助 curl 發送請求時,一些服務器推送事件的樣子:

$ curl -N 'http://localhost:3000/sessions/15/stream'
event: panda
data: one
event: panda
data: two
event: panda
data: three
event: elephant
data: four

服務器可以根據時間推移緩慢推送事件,并且客戶端也能夠在它們到來時讀取它們。你也可以將 JSON 或任何你想要的東西放在事件當中,就比如 data: {'name': 'ahmed'}

線路協議真的很簡單(只需要設置 event: 和 data:,或者如果你愿意,可設置為 id: 和 retry:),所以你并不需要任何花里胡哨的服務器庫來實現服務器推送事件。

JavaScript 的代碼也超級簡單(僅使用 EventSource)

以下是用于流式服務器推送事件的瀏覽器 JavaScript 的代碼。(我從 服務器推送事件的 MND 頁面 得到的這個范例)

你可以訂閱所有事件,也可以為不同類型的事件使用不同的處理程序。這里我有一個只接受類型為 panda 的事件的處理程序(就像我們的服務器在上一節中推送的那樣)。

const evtSource = new EventSource("/sessions/15/stream", { withCredentials: true })
evtSource.addEventListener("panda", function(event) {
  console.log("status", event)
});

客戶端在中途不能推送更新

不同于 Websockets,服務器推送事件不允許大量的來回事件通訊。(這體現在它的字眼中 —— 服務器 推送所有事件)。初始的時候客戶端發出一個請求,然后服務器發出一連串響應。

如果 HTTP 連接結束,它會自動重連

使用 EventSource 發出的 HTTP 請求和常規 HTTP 請求有一個很大的區別,MDN 文檔中對此有所說明:

默認情況下,如果客戶端和服務器之間的連接斷開,則連接會重啟。請使用 .close() 方法來終止連接。

很奇怪,一開始我真的被它嚇到了:我打開了一個連接,然后在服務器端將其關閉,然后兩秒過后客戶端向我的傳送終端發送了另一條請求!

我覺得這里可能是因為連接在完成之前意外斷開了,所以客戶端自動重新打開了它以防止類似情況再發生。

所以如果你不想讓客戶端繼續重試,你就得通過調用 .close() 直截了當地關閉連接。

這里還有些其它特性

你還能在服務器推送事件中設置 id: 和 retry: 字段。似乎,如果你在服務器推送事件上設置,那么當重新連接時,客戶端將發送一個 Last-Event-ID 響應頭,帶有它收到的最后一個 ID。酷!

我發現 W3C 的服務器推送事件頁面 令人驚訝地容易理解。

在設置服務器推送事件的時候我遇到了兩個錯誤

我在 Rails 中使用服務器推送事件時遇到了幾個問題,我認為這些問題挺有趣的。其中一個緣于 Nginx,另一個是由 Rails 引起的。

問題一:我不能在事件推送的過程中暫停

這個奇怪的錯誤是在我做以下操作時出現的:

def handler
    # SSE is Rails' built in server-sent events thing
    sse = SSE.new(response.stream, event: "status")
    sse.write('event')
    sleep 1
    sse.write('another event')
end

它會寫入第一個事件,但不能寫入第二個事件。我對此-非-常-困-惑,然后放開腦洞,試著理解 Ruby 中的 sleep 是如何運作的。但是 Cass 將我引領到一個與我有著相同困惑的 Stack Overflow 問答帖,而這里包含了讓我為之震驚的回答!

事實證明,問題出在我的 Rails 服務器位于 Nginx 之后,似乎 Nginx 默認使用 HTTP/1.0 向上游服務器發起請求(為啥?都 2021 年了,還這么干?我相信這其中一定有合乎情理的解釋,也許是為了向下兼容之類的)。

所以客戶端(Nginx)會在服務器推送第一個事件之后直接關閉連接。我覺得如果在我推送第二個事件的過程中 沒有 暫停,它繼續正常工作,基本上就是服務器在連接關閉之前和客戶端在爭速度,爭著推送第二部分響應,如果我這邊推送速度足夠快,那么服務器就會贏得比賽。

我不確定為什么使用 HTTP/1.0 會使客戶端的連接關閉(可能是因為服務器在每個事件結尾寫入了兩個換行符?),但因為服務器推送事件是一個比較新的玩意兒,HTTP/1.0 (這種老舊協議)不支持它一點都會不意外。

設置 proxy_http_version 1.1 從而解決那個麻煩。好欸!

問題二:事件被緩沖

這個事情解決完,第二個麻煩接踵而至。不過這個問題實際上非常好解決,因為 Cass 已經建議將 stackoverflow 里另一篇帖的回答 作為前一個問題的解決方案,雖然它并沒有是導致問題一出現的源頭,但它-確-實-解-釋-了問題二。

問題在這個示例代碼中:

def handler
    response.headers['Content-Type'] = 'text/event-stream'
    # Turn off buffering in nginx
    response.headers['X-Accel-Buffering'] = 'no'
    sse = SSE.new(response.stream, event: "status")
    10.times do
        sse.write('event')
        sleep 1
    end
end

我本來期望它每秒返回 1 個事件,持續 10 秒,但實際上它等了 10 秒才把 10 個事件一起返回。這不是我們想要的流式傳輸方式!

原來這是因為 Rack ETag 中間件想要計算 ETag(響應的哈希值),為此它需要整個響應為它服務。因此,我需要禁用 ETag 生成。

Stack Overflow 的回答建議完全禁用 Rack ETag 中間件,但我不想這樣做,于是我去看了 鏈接至 GitHub 上的議題

那個 GitHub 議題建議我可以針對僅流式傳輸終端應用一個解決方法,即 Last-Modified 響應頭,顯然,這么做可以繞過 ETag 中間件。

所以我設置為:

headers['Last-Modified'] = Time.now.httpdate

然后它起作用了!!!

我還通過設置響應頭 X-Accel-Buffering: no 關閉了位于 Nginx 中的緩沖區。我并沒有百分百確定我要那樣做,但這么做似乎更安全。

Stack Overflow 很棒

起初,我全身心致力于從頭開始調試這兩個錯誤。Cass 為我指向了那兩個 Stack Overflow 帖子,一開始我對那些帖下提出的解決方案持懷疑態度(我想:“我沒有使用 HTTP/1.0 啊!ETag 響應頭什么玩意,跟這一切有關系嗎??”)。

但結果證明,我確實無意中使用  HTTP/1.0,并且 Rack ETag 中間件確實給我帶來了問題。

因此,也許這個故事告訴我,有時候計算機就是會以奇怪的方式相互作用,其它人在過去也遇到過計算機以完全相同的奇怪方式相互作用的問題,而 Stack Overflow 有時會提供關于為什么會發生這些情況的答案 : )

我認為重要的是不要隨意從 Stack Overflow 中嘗試各種解決方案(當然,在這種情況下不會有人建議這樣做!)。對于這兩個問題,我確實需要去仔細思考,了解發生了什么,還有為什么更改這些設置會起作用。

就是這樣!

今天我要繼續著手實現服務器推送事件,因為昨天一整天我都沉浸在上述這些錯誤里。好在我學到了一個以前從未聽說過的易學易用的網絡技術,心里還是很高興的。

責任編輯:龐桂玉 來源: Linux中國
相關推薦

2020-03-09 08:24:06

TengineWeb代理服務器

2011-04-22 10:36:09

Server Push推送技術

2009-12-07 10:25:52

服務器安全服務器事件查看器

2012-02-16 11:35:34

ibmdw

2011-12-08 13:04:06

JavaNIO

2013-12-24 13:59:03

2009-12-07 10:19:16

2024-04-07 09:41:18

SignalR實時通信開發

2018-06-07 10:29:34

SDN服務器負載均衡

2021-03-18 09:31:56

微軟Exchange攻擊

2013-12-23 09:38:11

2016-09-08 22:54:14

2022-09-14 12:01:35

服務器入侵篡改,

2020-03-20 10:00:12

服務器網絡攻擊黑客

2025-03-26 00:00:00

Spring服務器推送技術

2013-04-26 11:42:00

2010-03-02 17:43:05

APC服務器機房

2009-10-27 16:24:22

APC服務器機房解決方

2010-09-13 10:53:09

2012-02-22 14:26:17

服務器云計算
點贊
收藏

51CTO技術棧公眾號

最爽无遮挡行房视频在线| 久久久久99| 久久精品国产v日韩v亚洲| 三级中文字幕在线观看| 国产一区二区激情| 日韩高清一区| 国产成人在线精品| 欧美精品1区| 影音欧美亚洲| 中文字幕精品—区二区四季| www.aqdy爱情电影网| 欧美亚洲国产一区二区三区va | 国产精品一区在线| 精品欧美一区免费观看α√| 国产精品日日摸夜夜摸av| 国产高清视频在线| 色综久久综合桃花网| 综合亚洲色图| 日本一区二区免费看| 国产蜜臀av在线一区二区三区| 色猫av在线| 久久亚洲精品一区二区| 亚洲一本二本| 久久精品网站视频| 69堂精品视频| 亚洲成在人线免费观看| 男女激烈动态图| 欧美亚日韩国产aⅴ精品中极品| 精品久久99| 欧美欧美一区二区| 亚洲一区二区三区四区中文字幕| 依依综合在线| 水蜜桃一区二区| 亚洲成人精品在线观看| 88xx成人永久免费观看| 国产精品对白刺激久久久| 国产欧美一区二区精品婷婷| 六月丁香久久丫| 欧美三级电影在线看| 久久久久国产精品| 精品美女在线观看视频在线观看| 亚洲av综合色区| 国产精品久久久久久久app| 91福利精品视频| 国产成人av一区二区| 国产一区二区三区91| av毛片在线看| av无码精品一区二区三区| 性色av香蕉一区二区| 亚洲成人你懂的| 日本特黄久久久高潮| 一区二区三区亚洲变态调教大结局| 无夜福利视频观看| 亚洲一区二区在线免费观看| 久久久久日韩精品久久久男男 | 久久久久99| 国产精品专区在线| 亚洲欧美中文日韩在线| 中文字幕五月欧美| 麻豆一区二区三| 三级电影一区| 九九九精品视频| 国产精品久久麻豆| 白浆爆出在线观看| 国产女人18毛片| 国产日韩亚洲精品| 欧美成人亚洲成人| 欧美视频精品在线| 国产精品丝袜一区| 日韩专区在线视频| 你懂的国产精品| 色吊丝一区二区| 男人av在线播放| 亚洲欧美视频一区二区| 天堂av电影在线观看| 美女胸又www又黄的网站| 国产超碰在线播放| 成年人在线观看视频免费| 亚洲狼人综合干| 国产精品久久久久免费a∨大胸| 欧美日韩一区二区三区四区| 成人一区二区三区视频| 成人污版视频| 国产cdts系列另类在线观看| 亚洲 高清 成人 动漫| 亚洲xxxx18| 国模精品一区二区三区色天香| 亚洲欧美另类综合偷拍| 欧美精品日本| 国产精品99久久久久久董美香 | 久久一区亚洲| www黄色av| 亚洲精品wwww| 国产精品啊啊啊| 日韩av在线影院| 欧美一区二区视频在线观看| 国产精品久久久久久久久久小说| 成人一级生活片| 国产最新在线| 日韩三级影视基地| 亚洲福利影视| 奇米色一区二区| 91精品国产麻豆| 青青草久久网络| caopo在线| 国产精品一二三在| 夜夜躁日日躁狠狠久久88av| 亚洲欧洲美洲在线综合| 亚洲精品一区二区三区av| 香蕉国产在线| 亚洲激情女人| 日韩精品中文字幕在线不卡尤物| 欧美一区二区三区在线播放| 在线观看福利电影| 久久亚洲欧美国产精品乐播 | 亚洲一区美女视频在线观看免费| 超碰在线94| 国产一区二区三区四区老人| 在线不卡的av| 国产成人生活片| 高清在线一区| 精品国产31久久久久久| 久久99久久精品国产| 伊人久久国产| 国产亚洲精品免费| 成人h视频在线观看| 日本在线视频www鲁啊鲁| 成人国产亚洲欧美成人综合网| 26uuu国产精品视频| 天堂av最新在线| 中文字幕亚洲精品在线观看 | 日本在线高清视频一区| 91麻豆精品| 欧美午夜片在线看| 久久久噜噜噜www成人网| 水蜜桃精品av一区二区| 亚洲一区二区国产| 亚洲综合在线小说| 中文成人在线| 91精品午夜视频| 99热一区二区| 国产麻豆综合| 国产成人精品久久| 亚洲播播91| 6080午夜不卡| 在线一区观看| 国产精品美女久久久久aⅴ国产馆 国产精品美女久久久久av爽李琼 国产精品美女久久久久高潮 | 日产精品久久久一区二区福利| 羞羞电影在线观看www| 亚洲激情六月丁香| 少妇高潮毛片色欲ava片| 99精品视频免费| 国产精品自产拍高潮在线观看| 精品国产一区二| 国产一区二区三区直播精品电影| a√资源在线| 亚洲电影激情视频网站| 日韩av一二三四| 成人一区在线观看| 日韩精品无码一区二区三区| 牛牛国产精品| 国产精品99导航| 美日韩黄色大片| 欧美激情视频三区| 天堂久久av| 色多多国产成人永久免费网站| 日本在线视频www鲁啊鲁| 欧美一区二区在线观看| www免费网站在线观看| 欧美日韩亚洲一区二区| 亚洲私人影吧| 欧美在线观看视频在线| 亚洲国产精华液| 精品国产福利在线| h视频在线播放| 日韩欧美不卡一区| av资源在线播放| 国产香蕉97碰碰久久人人| 欧美xxx视频| 精品国模在线视频| 亚洲精品在线影院| 日韩国产精品亚洲а∨天堂免| 欧美三级网址| 正在播放亚洲1区| 日韩视频在线直播| 欧美在线免费看| 欧美 日韩 国产精品免费观看| av一区二区三区免费| 亚洲一区国产| 免费一级淫片aaa片毛片a级| youjizz久久| 中文字幕天天干| 亚洲成人免费视频| 国产九九在线| 日韩一区二区高清| 亚洲国产欧美国产第一区| 国产综合香蕉五月婷在线| 日韩和欧美一区二区三区| 啊啊啊一区二区| 午夜激情综合网|