Home >Web Front-end >JS Tutorial >Server-sent Events

Server-sent Events

尊渡假赌尊渡假赌尊渡假赌
尊渡假赌尊渡假赌尊渡假赌Original
2025-02-27 09:25:10871browse

Server-sent Events

Core points

  • Server Send Events (SSE) is a method of pushing data and/or DOM events from the server to the client using streams, and is ideal for situations where data needs to be updated regularly, such as sports scores or stock quotes.
  • Creating EventSource objects allows you to subscribe to event streams and can handle open, message, and error events.
  • Sending events from the server requires the content to be provided using the Content-type header (value text/event-stream) and UTF-8 character encoding. The syntax for the server to send events includes data, event type, event identifier, and retry interval.
  • Event handling can use the onmessage function (only for applications that send message events), but the addEventListener method is more flexible for handling custom events.
  • Most modern browsers (including Chrome, Firefox, and Safari) support server sending events (SSE), but Internet Explorer does not. For applications that require support for all browsers, WebSockets or long polling may be more appropriate.
  1. Introduction
  2. Subscribe to stream: EventSource object
  3. Send events from server
    1. Send message event
    2. Send custom events
    3. Reconnect using retry interval management
    4. Set unique identifier using the id field
  4. Processing Events
  5. Processing error
  6. Browser implementation differences
  7. Browser support and fallback strategy

Suppose your country's national basketball team is participating in the World Basketball Championship. You want to follow the game, but you can't watch it because the game time conflicts with your working hours.

Luckily, your National News Service has a very outstanding web development team. They built a sports information scrolling display that updates whenever a foul or score occurs. When you visit a URL, the update will be pushed directly to your browser. Of course, you'll want to know how they did it. The answer is: the server sends the event.

Server Send Events is a way to use a stream to push data and/or DOM events from the server to the client. It is suitable for stock quotes, sports scores, flight tracking, email notifications – any situation where data needs to be updated regularly.

Wait! I heard you say, Can't we already do this using XMLHttpRequest or WebSockets? Yes, yes. However, doing so requires extending these objects to implement the functionality of EventSource itself.

Precautions on server side

Since the server sends events are data streams, they require long-term connections. You need to use a server that can handle a large number of simultaneous connections. Of course, event-driven servers are particularly suitable for streaming events. These include Node.js, Juggernaut, and Twisted. For Nginx, you can use the nginx-push-stream-module module. However, server configuration is outside the scope of this article and will vary depending on the server you are using.

Let's see how to subscribe to a stream using EventSource object. Then we will see how events are sent and processed.

Subscribe to event stream: EventSource object

Creating an EventSource object is simple.

<code class="language-javascript">var evtsrc = new EventSource('./url_of/event_stream/',{withCredentials:false});</code>

The EventSource constructor accepts up to two parameters:

  • A URL string (required); and
  • A Optional dictionary parameter used to define the value of the withCredentials attribute.

Dictionaries are syntactically similar to objects, but they are actually associative arrays of data with defined name-value pairs. In this case, withCredentials is the only possible dictionary member. Its value can be true or false. (For more information about dictionaries, see the Web IDL specification.)

Dictionary parameters are required only if cross-domain requests for user credentials (cookies). So far, no browser supports cross-domain EventSource requests. Therefore, we will not include the second parameter in the example.

When the EventSource connection is open, it will trigger a open event. We can define a function that handles the event by setting the onopen property.

<code class="language-javascript">var evtsrc = new EventSource('./url_of/event_stream/');
evtsrc.onopen = function(openevent){
    // 连接打开时执行的操作
}</code>

If there is a problem with our connection, an error will be triggered. We can use the onerror property to define a handler function for these events. We will discuss the causes of some error events in the "Training Errors" section.

<code class="language-javascript">evtsrc.onerror = function(openevent){
    // 发生错误时执行的操作
}</code>

Story events default to message events. To handle message events, we can use the onmessage attribute to define a handler function.

<code class="language-javascript">evtsrc.onmessage = function(openevent){
    // 接收到消息事件时执行的操作
}</code>

We can also use addEventListener() to listen for events. This is the only way to handle custom events, as we will see in the Processing Events section.

<code class="language-javascript">var onerrorhandler = function(openevent){
    // 执行的操作
}
evtsrc.addEventListener('error',onerrorhandler,false);</code>

To close the connection, use the close() method.

<code class="language-javascript">evtsrc.close();</code>

Therefore, we created the EventSource object and defined the handler for the opening, message, and error events. However, in order for this method to work, we need a URL for streaming events.

Send events from server

The server sends the event is a snippet of text delivered as part of the stream from the URL. In order for the browser to treat our data as a stream, we must:

  • Use the Content-type header (value is text/event-stream) to provide content;
  • Use UTF-8 character encoding.

The syntax for the server to send events is simple. It consists of one or more colon-separated field name-value pairs followed by a newline character. The field name can contain one of four possible values.

  • data:: The message to be sent.
  • event:: The type of event being dispatched.
  • id:: The event identifier to be used when the client reconnects.
  • retry:: How many milliseconds should pass before the browser tries to reconnect to the URL.

Among them, only the data field is required.

Send message event

In this example, we will send an event to announce which teams are playing in our tournament matches. When the browser receives this text, it dispatches a message event.

<code class="language-javascript">var evtsrc = new EventSource('./url_of/event_stream/',{withCredentials:false});</code>
The value of the

data field will become the value of the data attribute of the message event. As mentioned above, the server sends an event by default is a message event. But as we will discuss later, we can also dispatch custom events by including the event field.

We can also send several pieces of data as a single event. Each piece of data should be followed by a newline character (line newline, carriage return, or both). Here we are appending an event that includes this game location and attendance.

<code class="language-javascript">var evtsrc = new EventSource('./url_of/event_stream/');
evtsrc.onopen = function(openevent){
    // 连接打开时执行的操作
}</code>

For this event, the value of the data attribute will be: Air Canada CentrenToronto, Ontario, CanadaAttendance: 19,800.

Please note the blank lines between events. In order for the client to receive an event, the event must be followed by a blank line. Comments begin with a colon.

Send custom events

Unless we specify otherwise, the type of event is a message. To do this, we need to include a event field. In the following example, we will add two startingfive events to our stream and send our data as a string in JSON format.

<code class="language-javascript">evtsrc.onerror = function(openevent){
    // 发生错误时执行的操作
}</code>

Here, we need to listen to startingfive events instead of message events. However, our data field will still become the value of the data property of the event.

We will discuss the data properties and the MessageEvent interface in the "Processing Events" section.

Manage connections and reconnects

Now, although the server does push events to the browser, the reality is more subtle. If the server keeps the connection open, the EventSource request will be an extended request. If it is closed, the browser will wait a few seconds before reconnecting. For example, if the URL sends an end-of-file tag, the connection may be closed.

Each browser has its own default reconnect interval. Most will reconnect after 3 to 6 seconds. However, you can control this interval by including the retry field. The retry field indicates how many milliseconds the client should wait before reconnecting to the URL. Let's build and change our event from the example above to include a 5 second (5000 milliseconds) retry interval.

<code class="language-javascript">evtsrc.onmessage = function(openevent){
    // 接收到消息事件时执行的操作
}</code>

Event streams can be kept active as long as the client is connected. Depending on your architecture and application, you may want the server to close the connection periodically.

Set unique identifier using the id field

When the browser reconnects to the URL, it will receive any data available at the connection point. However, for the game information scrolling display, we may want to let the visitor know what he or she has missed. This is why the best practice for setting id to each event. In the following example, we are sending id as part of the scoring event.

<code class="language-javascript">var evtsrc = new EventSource('./url_of/event_stream/',{withCredentials:false});</code>

The value should be unique to the stream. In this case, we are using the time of the shot score.

The

id field becomes the lastEventId property of this event object. But it has another purpose. If the connection is closed, the browser will include a Last-Event-ID header in its next request. Think of it as a bookmark for the stream. If the Last-Event-ID header exists, you can adjust the application's response so that only events that follow it are sent.

Processing Events

As mentioned above, all events default to message events. Each message event has three properties, defined by the MessageEvent interface.

event.data
Returns data or message sent as part of the message event.
event.origin
Returns the source of the message, which is usually a string containing the scheme to send the message (for example: http, https), hostname, and port.
event.lastEventId
Returns the unique identifier of the last event received.
Whenever a message event is triggered, our onmessage function will be called. This works great for applications that you only send message events. However, if you want to send a score or startingfive event (as shown in our example), its limitations become obvious. More flexible using addEventListener. In the following code, we are using addEventListener to handle the startingfive event.
<code class="language-javascript">var evtsrc = new EventSource('./url_of/event_stream/');
evtsrc.onopen = function(openevent){
    // 连接打开时执行的操作
}</code>

(Second part, due to space limitations, please ask questions in paragraphs.)

The above is the detailed content of Server-sent Events. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn