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