HTML5 Server-Sent Events(伺服器發送事件) 教學範例 for PHP

透過 HTML5 Web API Server-Sent Events(伺服器發送事件) 搭配 PHP 來實作 Server 主動單向發送訊息給 Client Browser 的詳細教學與程式實作範例。
EventSource – Client
建立物件
判斷 Browser 有支援在建立 EventSource 物件,並指定 Server 檔案路徑:
事件
添加 EventSource 物件會用到的三種事件,說明如下表:
事件表
事件處理程序 | 事件處理程序事件類型 | 說明 |
---|---|---|
onopen | open | 與 Server 成功建立連結 |
onmessage | message | 監聽 Server 傳來的訊息,當接收到連續兩個換行 \n\n |
onerror | error | 與 Server 連結發生錯誤 |
PHP – Server
程式運作時間
Server-Sent Events 與 Server 連結後會持續的運作程式,而 PHP 預設運作的時間為 30 秒,因此必須修改為 0 不限制。
新增於程式碼開頭:
or 修改 php.ini 檔(須重啟服務):
表頭
Server 程式要能夠發送事件流必須將 Content-Type 表頭設置為 text/event-stream:
表頭必須設置禁止瀏覽器快取網頁(不緩存內容):
Nginx 設定
針對 Nginx 立即輸出緩衝區資料:
伺服器緩衝
預設情況是當程式結束後才會將資料一次送出(輸出)至 Browser,但使用 Server-Sent Events 應立即輸出每次的資料,因此必須設定緩衝讓資料立即輸出。
ob_flush()
與 flush()
有先後順序首先將緩衝區資料輸出給 Server,但並不是輸出到螢幕上:
在將 Server 上準備輸出的資料輸出至 Browser 顯示出來:
事件流格式
限制條件:
- 程式必須指定為 UTF-8 格式編碼
- 訊息內不能有空格、換行
一個字段的組成:
- 名稱
- 冒號
- 空格
- 值
"id: D121xxxxxx"
設置多個字段,使用 \n 界定符號:
"id: D121xxxxxx\ndata: {name: '王小傑', date: '2017-01-01'}"
使用連續兩個換行 \n\n 來送出一則訊息。當 Server 送出連續兩個換行 \n\n,EventSource 就會把它當成一個事件(預設自動觸發 onmessage 事件):
"\n\n"
字段表
字段名稱 | 說明 |
---|---|
event | 自行指定 Client 觸發的 event 名稱,如未指定預設為 onmessage |
data | 如果包含多個資料可使用 \n 界定符號,Client 會用界定符號將它們連接成一個字串 |
id | 事件 ID,會成為目前 EventSource 的內部屬性 |
retry | 整數值,指定重新連結的時間(毫秒)。非整數值會被忽略 |
範例
程式
Client
Server
執行結果
- 左側為 EventSource 連結的 Server 檔案
- 右側目前已收接了五則訊息,而接收的字段有 id(字串格式)與 data(json 格式)
- Browser 顯示的資訊則是從字段 data 的 json 格式,處理後添加 DOM 呈現的
- 要中斷 EventSource 連結,可點擊「中斷 Server 連線」按鈕

線上
下載
參考

本著作係採用創用 CC 姓名標示-相同方式分享 3.0 台灣 授權條款授權.
非常有用的!
奇怪,同样代码,我设置半天不生效,一直是页面100%loading 才一次显示,是还有什么别的需要配置的吗?THX~