翻譯不完整。請協助 翻譯此英文文件。
開發一個使用 server-sent 事件的網頁應用程式很簡單。在伺服器端只需要一些的程式碼與網頁串流事件,而客戶端這邊的處理方式和其他事件處理方式幾乎相同。
從伺服器端接收事件
server-sent event API 包含在 EventSource
接口;為了與伺服器端開啟連線並接收事件,需要創建一個標註伺服器腳本的 EventSource
物件。例如:
var evtSource = new EventSource("ssedemo.php");
If the event generator script is hosted on a different domain a new EventSource
object should be created that specifies both the URI and options dictionary. 例如, assuming the client script is on example.com:
var evtSource = new EventSource("//api.example.com/ssedemo.php", { withCredentials: true } );
註: 使用 EventSource
並未被所有的瀏覽器支援. 請檢查瀏覽器的相容性.
當你建構好你的 event source,就可以開始監聽伺服器傳來的訊息:
evtSource.onmessage = function(e) { var newElement = document.createElement("li"); newElement.innerHTML = "message: " + e.data; eventList.appendChild(newElement); }
This code listens for incoming messages (that is, notices from the server that do not have an event
field on them) and appends the message text to a list in the document's HTML.
你也可以利用 addEventListener()
監聽事件:
evtSource.addEventListener("ping", function(e) { var newElement = document.createElement("li"); var obj = JSON.parse(e.data); newElement.innerHTML = "ping at " + obj.time; eventList.appendChild(newElement); }, false);
This code is similar, except that it will be called automatically whenever the server sends a message with the event
field set to "ping"; it then parses the JSON in the data
field and outputs that information.
從伺服器發送事件
The server-side script that sends events needs to respond using the MIME type text/event-stream. Each notification is sent as a block of text terminated by a pair of newlines. For details on the format of the event stream, see Event stream format.
下面是一個 PHP 範例:
date_default_timezone_set("America/New_York"); header("Content-Type: text/event-stream\n\n"); $counter = rand(1, 10); while (1) { // Every second, sent a "ping" event. echo "event: ping\n"; $curDate = date(DATE_ISO8601); echo 'data: {"time": "' . $curDate . '"}'; echo "\n\n"; // Send a simple message at random intervals. $counter--; if (!$counter) { echo 'data: This is a message at time ' . $curDate . "\n\n"; $counter = rand(1, 10); } ob_flush(); flush(); sleep(1); }
The code above generates an event every second, with the event type "ping". Each event's data is a JSON object containing the ISO 8601 timestamp corresponding to the time at which the event was generated. At random intervals, a simple message (with no event type) is sent.
錯誤處理
When problems occur (such as a network timeout or issues pertaining to access control), an error event is generated. You can take action on this programmatically by implementing the onerror
callback on the EventSource object:
evtSource.onerror = function(e) { alert("EventSource failed."); };
As of Firefox 22, it does not appear that there is any way to distinguish between different kinds of error events.
關閉事件串流
By default, if the connection between the client and server closes, the connection is reset. The connection is terminated with the .close()
method.
evtSource.close();
事件串流(Event Stream)格式
Event stream 是個簡單的純文字檔。其必須以 UTF-8 格式編碼。在 Event stream 中,不同的訊息以一對換行符號做區分。若要撰寫註解,要在一行的開頭加上冒號(:)。
Each message consists of one or more lines of text listing the fields for that message. Each field is represented by the field name, followed by a colon, followed by the text data for that field's value.
Fields
規格書中定義 Event Stream 以下欄位
event
- The event's type. If this is specified, an event will be dispatched on the browser to the listener for the specified event name; the web site source code should use
addEventListener()
to listen for named events. Theonmessage
handler is called if no event name is specified for a message. data
- The data field for the message. When the EventSource receives multiple consecutive lines that begin with
data:
, it will concatenate them, inserting a newline character between each one. Trailing newlines are removed. id
- The event ID to set the
EventSource
object's last event ID value. retry
- The reconnection time to use when attempting to send the event. [What code handles this?] This must be an integer, specifying the reconnection time in milliseconds. If a non-integer value is specified the field is ignored.
除上述的幾個欄位,其他欄位均會被忽略。
範例
Data-only messages
In the following example, there are three messages sent. The first is just a comment, since it starts with a colon character. As mentioned previously, this can be useful as a keep-alive if messages may not be sent regularly.
The second message contains a data field with the value "some text". The third message contains a data field with the value "another message\nwith two lines". Note the newline special character in the value.
: this is a test stream data: some text data: another message data: with two lines
命名地事件
This example sends some named events. Each has an event name specified by the event
field, and a data
field whose value is an appropriate JSON string with the data needed for the client to act on the event. The data
field could, of course, have any string data; it doesn't have to be JSON.
event: userconnect data: {"username": "bobby", "time": "02:33:48"} event: usermessage data: {"username": "bobby", "time": "02:34:11", "text": "Hi everyone."} event: userdisconnect data: {"username": "bobby", "time": "02:34:23"} event: usermessage data: {"username": "sean", "time": "02:34:36", "text": "Bye, bobby."}
Mixing and matching
You don't have to use just unnamed messages or typed events; you can mix them together in a single event stream.
event: userconnect data: {"username": "bobby", "time": "02:33:48"} data: Here's a system message of some kind that will get used data: to accomplish some task. event: usermessage data: {"username": "bobby", "time": "02:34:11", "text": "Hi everyone."}
瀏覽器相容性
Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
EventSource support | 9 | 6.0 (6.0) | Not supported | 11 | 5 |
Feature | Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|
EventSource support | 42 | ? | ? | 11.1 | 4 |