摘要:簡介是的縮寫。通常情況下,是我們的瀏覽器向服務(wù)器發(fā)起請(qǐng)求后,服務(wù)器響應(yīng),然后關(guān)閉連接。為了能夠保持通信,以便在服務(wù)器有事件發(fā)生時(shí)主動(dòng)通知瀏覽器,后來人們又發(fā)明了很多技術(shù),包括等。
SSE簡介
SSE是Server-Sent Events的縮寫。通常情況下,是我們的瀏覽器向服務(wù)器發(fā)起請(qǐng)求后,服務(wù)器響應(yīng),然后關(guān)閉連接。為了能夠保持通信,以便在服務(wù)器有事件發(fā)生時(shí)主動(dòng)通知瀏覽器,后來人們又發(fā)明了很多技術(shù),包括websocket等。但是websocket對(duì)于代碼改動(dòng)較大,所以又出現(xiàn)了SSE,它的特點(diǎn)是基本不用改寫原有的邏輯,只是增加一些小的改動(dòng)就能實(shí)現(xiàn)服務(wù)器與客戶端之間的長連接,達(dá)到服務(wù)器主動(dòng)通知客戶端的目的。
但是我在按照網(wǎng)上教程真正去在nginx環(huán)境下實(shí)現(xiàn)SSE時(shí),頗費(fèi)了一番周章,留在這里,以便有同學(xué)遇到類似問題時(shí)參考。
客戶端SSE的主要原理是由客戶端,也就是瀏覽器里的javascript發(fā)起一個(gè)類似于ajax的請(qǐng)求,但和ajax不同的是,這是一個(gè)一直保持的長連接,一旦請(qǐng)求建立之后,客戶端開始安靜地等待服務(wù)端向它發(fā)回?cái)?shù)據(jù),這個(gè)連接可以保持很長很長時(shí)間。
所以客戶端的代碼很簡單:
source = new EventSource("http://api.server.com/path/file.php?param=value"); source.onmessage = function (event) { json = JSON.parse(event.data); ... 后面是你處理數(shù)據(jù)的部分 ... };
不用擔(dān)心斷掉,即使斷掉的話,客戶端會(huì)在斷掉之后的3秒之后自動(dòng)再次重新向服務(wù)端發(fā)起連接請(qǐng)求,而且這個(gè)重新連接是瀏覽器自動(dòng)幫助我們實(shí)現(xiàn)的,我們?cè)诰幊虝r(shí)可以完全不去考慮它。
服務(wù)器端 php部分header("Access-Control-Allow-Origin: http://www.server.com"); //發(fā)送SSE應(yīng)答 header("X-Accel-Buffering: no"); header("Content-Type: text/event-stream"); header("Cache-Control: no-cache"); $old_md5 = ""; //執(zhí)行100次,每次睡眠3秒鐘,總共300秒,也就是5分鐘 for ($i=0; $i<100; $i++) { //保持一個(gè)長連接,每隔3秒鐘回答客戶端一次 $o_data = 你的數(shù)據(jù); $str_return = json_encode($o_data); $md5 = md5($str_return); if ($md5 != $old_md5) { //如果內(nèi)容發(fā)生了變化,則推送,否則不必推送,以節(jié)省網(wǎng)絡(luò)流量 echo "data: " . $str_return . " "; $old_md5 = $md5; } ob_flush(); flush(); //等待3秒鐘,開始下一次查詢 sleep(3); }
逐行分解一下:
這三句話必不可少:
header("X-Accel-Buffering: no"); header("Content-Type: text/event-stream"); header("Cache-Control: no-cache");
其中的第一句話,是配置nginx必需的。因?yàn)?b>nginx缺省會(huì)對(duì)所有來自php的數(shù)據(jù)作緩存,它一定要等到所有數(shù)據(jù)全部寫進(jìn)緩存后才一股腦發(fā)給客戶端,而我們要建立的是一個(gè)很長的連接,這個(gè)連接過程中隨時(shí)可能要發(fā)送數(shù)據(jù),不需要緩存,所以這里必須通過X-Accel-Buffering告訴nginx你對(duì)我這段代碼不要給我做緩存,否則你會(huì)在客戶端等很長很長時(shí)間卻一個(gè)字符也收不到。
注意后面那個(gè)100次的for循環(huán),網(wǎng)上幾乎所有的例子里在這里都會(huì)使用while(1)的一個(gè)無限循環(huán),但我個(gè)人的經(jīng)驗(yàn)恰恰相反,在這里應(yīng)該是一個(gè)for循環(huán),而不是while循環(huán)。為什么呢?因?yàn)槲覀儽仨毷沟谜麄€(gè)程序的執(zhí)行時(shí)間可控,如果你用for循環(huán)100次,每次sleep 3秒鐘的話,整個(gè)腳本的執(zhí)行時(shí)長也就是在5分鐘左右,而如果你使用while無限循環(huán)的話,整個(gè)時(shí)間會(huì)幾乎是無限長。有的同學(xué)可能會(huì)說我在php.ini里設(shè)置了max_excution_time是60秒鐘啊,很好,我一開始也是這么認(rèn)為的,但是:sleep(3)的時(shí)間不算在內(nèi)!所以你可以想象一下你的腳本要執(zhí)行多長時(shí)間才會(huì)結(jié)束并安靜地從內(nèi)存中退出去?
nginx設(shè)置最后,還需要配置nginx,只需要一句話,在你的nginx.conf的location里:
fastcgi_read_timeout 600s;
這是由于nginx在和我們的php-fpm進(jìn)行通訊的時(shí)候,這個(gè)地方的缺省值是60,如果它等了60秒,結(jié)果php-fpm一個(gè)字符也沒有送過來的話,nginx會(huì)強(qiáng)行中止與我們的程序的連接,但我們的程序?qū)嶋H還沒有執(zhí)行結(jié)束,這時(shí)候js客戶端發(fā)現(xiàn)連接斷了,就會(huì)自動(dòng)重啟一個(gè)新的連接,結(jié)果我們服務(wù)器端的資源很快被耗盡了。在這里設(shè)為600秒的意思是告訴nginx,即使我的php代碼一個(gè)字符也不給你發(fā)送,你也必須老老實(shí)實(shí)呆夠10分鐘才可以退出。而實(shí)際上是,還記得我們前面的for循環(huán)嗎?我們會(huì)在100次等待3秒后,也就是5分鐘內(nèi)退出我們的php腳本執(zhí)行,不會(huì)湊夠10分鐘的。所以這里很安全。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/39314.html
摘要:簡介是的縮寫。通常情況下,是我們的瀏覽器向服務(wù)器發(fā)起請(qǐng)求后,服務(wù)器響應(yīng),然后關(guān)閉連接。為了能夠保持通信,以便在服務(wù)器有事件發(fā)生時(shí)主動(dòng)通知瀏覽器,后來人們又發(fā)明了很多技術(shù),包括等。 SSE簡介 SSE是Server-Sent Events的縮寫。通常情況下,是我們的瀏覽器向服務(wù)器發(fā)起請(qǐng)求后,服務(wù)器響應(yīng),然后關(guān)閉連接。為了能夠保持通信,以便在服務(wù)器有事件發(fā)生時(shí)主動(dòng)通知瀏覽器,后來人們又發(fā)明...
摘要:或少了因?yàn)閱?dòng)時(shí)不是賬號(hào),就會(huì)這樣前面別忘了加文件直接下載,不解析因?yàn)闆]有配置的解決辦法引起通常是三種情況一是缺少索引文件,二是權(quán)限問題,三是狀態(tài)。 ========騰訊云重裝記錄================ 安裝時(shí)間:2018-09-09 12:15開始,結(jié)束時(shí)間: 一:重裝操作系統(tǒng) 進(jìn)入騰訊云后臺(tái),微信掃碼登錄 選擇主機(jī)/更多/重裝系統(tǒng)/服務(wù)市場/Docker容器/騰訊云容器...
摘要:或少了因?yàn)閱?dòng)時(shí)不是賬號(hào),就會(huì)這樣前面別忘了加文件直接下載,不解析因?yàn)闆]有配置的解決辦法引起通常是三種情況一是缺少索引文件,二是權(quán)限問題,三是狀態(tài)。 ========騰訊云重裝記錄================ 安裝時(shí)間:2018-09-09 12:15開始,結(jié)束時(shí)間: 一:重裝操作系統(tǒng) 進(jìn)入騰訊云后臺(tái),微信掃碼登錄 選擇主機(jī)/更多/重裝系統(tǒng)/服務(wù)市場/Docker容器/騰訊云容器...
閱讀 3915·2021-11-16 11:50
閱讀 927·2021-11-11 16:55
閱讀 3659·2021-10-26 09:51
閱讀 856·2021-09-22 15:03
閱讀 3409·2019-08-30 15:54
閱讀 3260·2019-08-30 15:54
閱讀 2468·2019-08-30 14:04
閱讀 919·2019-08-30 13:53