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 (valuetext/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 theaddEventListener
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.
- Introduction
- Subscribe to stream: EventSource object
- Send events from server
- Send message event
- Send custom events
- Reconnect using retry interval management
- Set unique identifier using the id field
- Processing Events
- Processing error
- Browser implementation differences
- 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.
var evtsrc = new EventSource('./url_of/event_stream/',{withCredentials:false});
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.
var evtsrc = new EventSource('./url_of/event_stream/'); evtsrc.onopen = function(openevent){ // 连接打开时执行的操作 }
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.
evtsrc.onerror = function(openevent){ // 发生错误时执行的操作 }
Story events default to message events. To handle message events, we can use the onmessage
attribute to define a handler function.
evtsrc.onmessage = function(openevent){ // 接收到消息事件时执行的操作 }
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.
var onerrorhandler = function(openevent){ // 执行的操作 } evtsrc.addEventListener('error',onerrorhandler,false);
To close the connection, use the close()
method.
evtsrc.close();
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 istext/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.
var evtsrc = new EventSource('./url_of/event_stream/',{withCredentials:false});
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.
var evtsrc = new EventSource('./url_of/event_stream/'); evtsrc.onopen = function(openevent){ // 连接打开时执行的操作 }
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.
evtsrc.onerror = function(openevent){ // 发生错误时执行的操作 }
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.
evtsrc.onmessage = function(openevent){ // 接收到消息事件时执行的操作 }
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.
var evtsrc = new EventSource('./url_of/event_stream/',{withCredentials:false});
The value should be unique to the stream. In this case, we are using the time of the shot score.
Theid
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.
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.
var evtsrc = new EventSource('./url_of/event_stream/'); evtsrc.onopen = function(openevent){ // 连接打开时执行的操作 }
(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!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

Frequently Asked Questions and Solutions for Front-end Thermal Paper Ticket Printing In Front-end Development, Ticket Printing is a common requirement. However, many developers are implementing...

JavaScript is the cornerstone of modern web development, and its main functions include event-driven programming, dynamic content generation and asynchronous programming. 1) Event-driven programming allows web pages to change dynamically according to user operations. 2) Dynamic content generation allows page content to be adjusted according to conditions. 3) Asynchronous programming ensures that the user interface is not blocked. JavaScript is widely used in web interaction, single-page application and server-side development, greatly improving the flexibility of user experience and cross-platform development.

There is no absolute salary for Python and JavaScript developers, depending on skills and industry needs. 1. Python may be paid more in data science and machine learning. 2. JavaScript has great demand in front-end and full-stack development, and its salary is also considerable. 3. Influencing factors include experience, geographical location, company size and specific skills.

How to merge array elements with the same ID into one object in JavaScript? When processing data, we often encounter the need to have the same ID...

Learning JavaScript is not difficult, but it is challenging. 1) Understand basic concepts such as variables, data types, functions, etc. 2) Master asynchronous programming and implement it through event loops. 3) Use DOM operations and Promise to handle asynchronous requests. 4) Avoid common mistakes and use debugging techniques. 5) Optimize performance and follow best practices.

Discussion on the realization of parallax scrolling and element animation effects in this article will explore how to achieve similar to Shiseido official website (https://www.shiseido.co.jp/sb/wonderland/)...

In-depth discussion of the root causes of the difference in console.log output. This article will analyze the differences in the output results of console.log function in a piece of code and explain the reasons behind it. �...

The latest trends in JavaScript include the rise of TypeScript, the popularity of modern frameworks and libraries, and the application of WebAssembly. Future prospects cover more powerful type systems, the development of server-side JavaScript, the expansion of artificial intelligence and machine learning, and the potential of IoT and edge computing.
