Movatterモバイル変換


[0]ホーム

URL:


  1. Web
  2. Web APIs
  3. Server-sent events
  4. Using server-sent events

Using server-sent events

Baseline Widely available *

This feature is well established and works across many devices and browser versions. It’s been available across browsers since ⁨January 2020⁩.

* Some parts of this feature may have varying levels of support.

Developing a web application that usesserver-sent events is straightforward. You'll need a bit of code on the server to stream events to the front-end, but the client side code works almost identically towebsockets in part of handling incoming events. This is a one-way connection, so you can't send events from a client to a server.

Receiving events from the server

The server-sent event API is contained in theEventSource interface.

Creating anEventSource instance

To open a connection to the server to begin receiving events from it, create a newEventSource object with the URL of a script that generates the events. For example:

js
const evtSource = new EventSource("sse-demo.php");

If the event generator script is hosted on a different origin, a newEventSource object should be created with both the URL and an options dictionary. For example, assuming the client script is onexample.com:

js
const evtSource = new EventSource("//api.example.com/sse-demo.php", {  withCredentials: true,});

Listening formessage events

Messages sent from the server that don't have anevent field are received asmessage events. To receive message events, attach a handler for themessage event:

js
evtSource.onmessage = (event) => {  const newElement = document.createElement("li");  const eventList = document.getElementById("list");  newElement.textContent = `message: ${event.data}`;  eventList.appendChild(newElement);};

This code listens for incoming message events and appends the message text to a list in the document's HTML.

Listening for custom events

Messages from the server that do have anevent field defined are received as events with the name given inevent. For example:

js
evtSource.addEventListener("ping", (event) => {  const newElement = document.createElement("li");  const eventList = document.getElementById("list");  const time = JSON.parse(event.data).time;  newElement.textContent = `ping at ${time}`;  eventList.appendChild(newElement);});

This code will be called whenever the server sends a message with theevent field set toping; it then parses the JSON in thedata field and outputs that information.

Warning:Whennot used over HTTP/2, SSE suffers from a limitation to the maximum number of open connections, which can be especially painful when opening multiple tabs, as the limit isper browser and is set to a very low number (6). The issue has been marked as "Won't fix" inChrome andFirefox. This limit is per browser + domain, which means that you can open 6 SSE connections across all of the tabs towww.example1.com and another 6 SSE connections towww.example2.com (perStack Overflow). When using HTTP/2, the maximum number of simultaneousHTTP streams is negotiated between the server and the client (defaults to 100).

Sending events from the server

The server-side script that sends events needs to respond using the MIME typetext/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, seeEvent stream format.

ThePHP code for the example we're using here follows:

php
date_default_timezone_set("America/New_York");header("X-Accel-Buffering: no");header("Content-Type: text/event-stream");header("Cache-Control: no-cache");$counter = rand(1, 10);while (true) {  // Every second, send 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);  }  if (ob_get_contents()) {      ob_end_flush();  }  flush();  // Break the loop if the client aborted the connection (closed the page)  if (connection_aborted()) break;  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.The loop will keep running independent of the connection status, so a check is includedto break the loop if the connection has been closed (e.g., client closes the page).

Note:You can find a full example that uses the code shown in this article on GitHub — seeSimple SSE demo using PHP.

Error handling

If the server responds with anerror key (e.g.,JSON.parse(event.data.error) or another problem occurs (such as a network timeout or issues pertaining toaccess control), an error event is generated. You can take action on this programmatically by implementing theonerror callback on theEventSource object:

js
evtSource.onerror = (err) => {  console.error("EventSource failed:", err);};

Closing event streams

By default, if the connection between the client and server closes, the connection is restarted. The connection is terminated with the.close() method.

js
evtSource.close();

Event stream format

The event stream is a simple stream of text data which must be encoded usingUTF-8. Messages in the event stream are separated by a pair of newline characters. A colon as the first character of a line is in essence a comment, and is ignored.

Note:The comment line can be used to prevent connections from timing out; a server can send a comment periodically to keep the connection alive.

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

Each message received has some combination of the following fields, one per line:

event

A string identifying the type of event described. If this is specified, an event will be dispatched on the browser to the listener for the specified event name; the website source code should useaddEventListener() 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 theEventSource receives multiple consecutive lines that begin withdata:,it concatenates them, inserting a newline character between each one. Trailing newlines are removed.

id

The event ID to set theEventSource object's last event ID value.

retry

The reconnection time. If the connection to the server is lost, the browser will wait for the specified time before attempting to reconnect. This must be an integer, specifying the reconnection time in milliseconds. If a non-integer value is specified, the field is ignored.

All other field names are ignored.

Note:If a line doesn't contain a colon, the entire line is treated as the field name with an empty value string.

Examples

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 mechanism if messages might 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.

bash
: this is a test streamdata: some textdata: another messagedata: with two lines

Named events

This example sends named events. Each has an event name specified by theevent field, and adata field whose value is an appropriate JSON string with the data needed for the client to act on the event. Thedata field could, of course, have any string data; it doesn't have to be JSON.

bash
event: userconnectdata: {"username": "bobby", "time": "02:33:48"}event: usermessagedata: {"username": "bobby", "time": "02:34:11", "text": "Hi everyone."}event: userdisconnectdata: {"username": "bobby", "time": "02:34:23"}event: usermessagedata: {"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.

bash
event: userconnectdata: {"username": "bobby", "time": "02:33:48"}data: Here's a system message of some kind that will get useddata: to accomplish some task.event: usermessagedata: {"username": "bobby", "time": "02:34:11", "text": "Hi everyone."}

Browser compatibility

Help improve MDN

Learn how to contribute

This page was last modified on byMDN contributors.


[8]ページ先頭

©2009-2025 Movatter.jp