【實作 Server 端】
所謂 Server-Sent Event 中文解釋為伺服器推送或伺服器推播,主要是用來將伺服器上的資料自動傳輸至 Client 端,使用的是 HTTP 通訊協定。首先需要 Server 端的應用程式,筆者以 ASP.NET 泛型處理常式來實作本文 Server 端的應用程式,您也可以利用 PHP、JSP 等其他 Server 端的程式語言來實作。
Server 端的程式推送給 Client 端的封包是由 event(事件或識別名稱,預設值為 message)、data(要傳送給 Client 端的資料內容)、id(Server 端推送資料到 Client 端時的事件ID) 和 retry(以毫秒為單位,用來定義兩次要求之間的間隔時間)等四個欄位所組成,其格式為【欄位名稱:欄位內容】。其中又以 data 欄位最為重要,若 Server 端沒有傳送該欄位給 Client 端,即便您定義了資料接收的事件,該事件仍不會被觸發。
下列程式碼用來示範將回傳目前 Server 端的系統時間給 Client 端的瀏覽器,其中 ContentType 必須要設定為【text/event-stream】整個 Server-Sent Events 機制才能正常運作。
02 |
using System.Collections.Generic; |
06 |
namespace ServerSendEvents |
11 |
public class ServerSide : IHttpHandler |
14 |
public void ProcessRequest(HttpContext context) |
16 |
context.Response.ContentType = "text/event-stream" ; |
17 |
context.Response.Write( string .Format( "data:{0}\n" , DateTime.Now.ToString())); |
20 |
public bool IsReusable |
【實作 Client 端】
Client 端要能接收 Server 端的推送資料,必須先建立 EventSource 物件,例如下列的程式碼,透過建構式傳入的 URL 來設定要從哪裡接收資料,接著 EventSource 物件便會以非同步方式來向 URL 參數所對應的 Server 端提出要求,以接收回傳的資料。
1 |
var es = new EventSource(url); |
處理 Server 端推送下來的資料時,有三個事件屬性可以使用,分別是 onopen(連線建立時觸發)、onmessage(接收到 Server 端推送的訊息時觸發) 與 onerror(連線失敗時觸發)。
01 |
var es = new EventSource( "ServerSide.ashx" ); |
04 |
es.onerror = function (e) { |
05 |
switch (e.target.readyState) { |
06 |
case EventSource.CONNECTING: |
09 |
case EventSource.CLOSED: |
13 |
document.getElementById( "divMsg" ).innerHTML += stat + "<br/>" ; |
16 |
es.onmessage = function (e) { |
17 |
document.getElementById( "divMsg" ).innerHTML += "現在時刻:" + e.data.toString() + "<br/>" ; |
20 |
es.onopen = function (e) { |
21 |
switch (e.target.readyState) |
23 |
case EventSource.CONNECTING: |
26 |
case EventSource.OPEN: |
29 |
case EventSource.CLOSED: |
36 |
document.getElementById( "divMsg" ).innerHTML += "連線狀態:" + stat + "<br/>" |
執行結果如下:
若您希望與 Server 端停止連線,可以呼叫 EventSource 的 Close 方法,例如下列的程式碼(其中 es 為上面所宣告的 EventSource 物件):
【變更重新連線的間隔時間】
由上一節的執行結果可知,預設 Server 端每 5000 毫秒推送一次資料到 Client 端的瀏覽器上,若您要調整這個間隔時間,可以在 Server 端設定 retry 欄位的值,例如下列的程式碼:
1 |
context.Response.Write(string.Format( "retry:{0}\n" , "1000" )); |
修改過後重新執行 Client 端網頁,您將看到如下圖的結果,已經由原本的每 5000 毫秒推送一次,變成每 1000 毫秒推送一次。
留言列表