HTML5 supports Server-Sent Events-one-way message transmission data push (C # example ),
Simple Sequence Diagram for traditional WEB applications to communicate:
Currently, most Web apps have Ajax, which is like this:
HTML5 has a Server-Sent Events (SSE) function that allows the Server to push data to the client. (Usually calledData push). Data push is like this. When the data source has new data, it is immediately sent to the client without waiting for client requests. These new data may be the most recent news, the latest stock prices, chat information from friends, weather forecasts, etc.
The data pulling and pushing functions are the same. Users get new data. However, data push has some advantages. You may have heard that Comet, Ajax push, reverse Ajax, HTTP stream, WebSockets, and SSE are different technologies. The biggest advantage is low latency. SSE is used by web applications to refresh data without any action.
You may have heard of HTML5 WebSockets and can also push data to the client. WebSockets is a more complex technology to implement the server, but it is a real full-duplex socket, the server can push data to the client, the client can also push data back to the server. SSE works on HTTP/HTTPS protocol and supports proxy server and authentication technology. SSE is a text protocol that you can easily debug. If you need to send most of the binary data from the server to the client, WebSocket is a better choice. The difference between SSE and WebSocket is described below.
Send events on the HTML5 Server(Server-sent event) allows the webpage to obtain updates from the server
Server-Sent event-One-way message transmission
Server-Sent events indicate that the webpage automatically obtains updates from the Server.
This was also possible in the past, provided that the webpage had to ask if there were any available updates. When an event is sent through the server, the update will automatically arrive.
Example: Facebook/Twitter updates, valuation updates, new blog posts, and competition results.
Browser support (all mainstream browsers support sending events to servers, except Internet Explorer .)
EventSource push (ajax normal polling ):
Processing Process:
The client creates an EventSource object and continuously requests the server over http. The response data format of the server to the client is composed of four parts: event, data, id, and space. After receiving the response data from the server, the client finds the event listener corresponding to the EventSource object based on the event value.
Receive Server-Sent Event Notifications
The EventSource object is used to receive event notifications from the server:
// Create a new EventSource object that specifies the URL var source = new EventSource (".. /api/MyAPI/ServerSentEvents "); // message event source is supported by default. onmessage = function (event) {console. log (source. readyState); console. log (event );};
Instance resolution:
Create a new EventSource object and specify the URL of the page to be updated ("demo_sse.php" in this example "),The parameter url is the server url, which must be in the same domain as the current webpage, and must have the same protocol and Port.
Onmessage event occurs every time an update is received.
Detect Server-Sent event support
For the following example, we have compiled an additional code to check the browser support for sending events on the server:
If (!! EventSource & typeof (EventSource )! = "Undefined") {// the browser supports Server-Sent // some code...} else {// the browser does not support Server-Sent ..}
Server code instance
To make the preceding example run, you also need servers that can send data updates (such as PHP, ASP, ASP. NET, and Java ).
The syntax of the server-side event stream is very simple. YouYou need to set the "Content-Type" header to "text/event-stream". Now you can start sending event streams.
I only use C #, so the ApiController in ASP. NET MVC writes the simplest Server:
Public class MyAPIController: ApiController {// <summary> ///... api/MyAPI/ServerSentEvents // </summary> // <returns> </returns> [HttpGet, HttpPost] public Task <HttpResponseMessage> ServerSentEvents () {// Response. contentType = "text/event-stream" // Response. expires =-1 // Response. write ("data:" & now () // Response. flush () string data = "id: 123456 \ nevent: message \ ndata: 666 \ n"; HttpResponseMessage response = new HttpResponseMessage {// note: contentType = "text/event-stream" Content = new StringContent (data, Encoding. getEncoding ("UTF-8"), "text/event-stream")}; return Task. fromResult (response );}}
Code explanation:
Set the header "Content-Type" to "text/event-stream"
Disable page caching
Output sending date (always starting with "data)
Refresh the output data to the webpage
EventSource object
The newly generated EventSource instance object has a readyState attribute, indicating the connection status.
Source.ReadyState
It can take the following values:
0, which is equivalent to the constant EventSource. CONNECTING, indicating that the connection has not been established or the connection is broken.
1, which is equivalent to the constant EventSource. OPEN, indicating that the connection has been established and data can be accepted.
2, equivalent to the constant EventSource. CLOSED, indicating that the connection is disconnected and will not be reconnected.
In the above example, we use the onmessage event to obtain the message. However, you can also use other events:
Event Description
OnopenWhen the connection to the server is opened
OnmessageWhen a message is received
OnerrorWhen an error occurs
Open events
Once a connection is established, an open event is triggered and a corresponding callback function can be defined.
Source. onopen = function (event ){
// Handle open event
};
// Or
Source. addEventListener ("open", function (event ){
// Handle open event
}, False );
Message event
A message event is triggered when data is received.
Source. onmessage = function (event ){
Var data = event. data;
Var origin = event. origin;
Var lasteven tid = event. lasteven tid;
// Handle message
};
// Or
Source. addEventListener ("message", function (event ){
Var data = event. data;
Var origin = event. origin;
Var lasteven tid = event. lasteven tid;
// Handle message
}, False );
The parameter object event has the following attributes:
Data: The data returned by the server (in text format ).
Origin: The domain name of the server URL, that is, the Protocol, domain name, and port.
Lasteven TID: The data number sent by the server. If there is no number, this attribute is blank.
Error Event
If a communication error occurs (such as a connection interruption), an error event is triggered.
Source. onerror = function (event ){
// Handle error event
};
// Or
Source. addEventListener ("error", function (event ){
// Handle error event
}, False );
Custom events
The server can customize events with the browser. In this case, the sent data does not trigger the message event.
Source. addEventListener ("foo", function (event ){
Var data = event. data;
Var origin = event. origin;
Var lasteven tid = event. lasteven tid;
// Handle message
}, False );
The code above indicates that the browser listens to the foo event.
Close Method
The close method is used to close the connection.
Source.Close ();
Data format
Overview
The HTTP header of the data sent by the server is as follows:
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
The subsequent rows are in the following format:
Field: value \ n
Field can take four values: "data", "event", "id", or "retry", that is, there are four types of header information. Each HTTP Communication can contain one or more of the four types of header information. \ N indicates a line break.
A line starting with a colon (:) indicates a comment. Generally, the server sends a comment to the browser at intervals to keep the connection uninterrupted.
: This is a comment
The following are some examples.
: This is a test stream \ n
Data: some text \ n
Data: another message \ n
Data: with two lines \ n
Data: data Column
The data content is represented by data, which can occupy one or more rows. If there is only one row of data, it ends with \ n as follows.
Data: message \ n
If there are multiple rows of data, the last row ends with "\ n", and the previous row ends with "\ n.
Data: begin message \ n
Data: continue message \ n
In short, the data in the last row must end with two line breaks, indicating that the data ends.
Take sending data in JSON format as an example.
Data: {\ n
Data: "foo": "bar", \ n
Data: "baz", 555 \ n
Data:} \ n
Id: Data identifier
The data identifier is represented by id, which is equivalent to the number of each data entry.
Id: msg1 \ n
Data: message \ n
The browser reads this value using the lasteven TID attribute. Once the connection is disconnected, the browser will send an HTTP header containing a special "Last-Event-ID" header and send this value back to help the server re-establish the connection. Therefore, this header information can be considered as a synchronization mechanism.
Event column: custom information type
The event header information indicates the custom data type or data name.
Event: foo \ n
Data: a foo event \ n
Data: an unnamed event \ n
Event: bar \ n
Data: a bar event \ n
The above Code creates three pieces of information. The first is foo, which triggers the foo event on the browser side. The second is not named, which indicates the default type and triggers the message event on the browser side. The third is bar, which triggers the bar event on the browser side.
Retry: maximum interval
By default, if the server does not send any information within three seconds, the server starts to reconnect. The server can use the retry header to specify the maximum communication interval.
Retry: 10000 \ n
Bytes --------------------------------------------------------------------------------------
Specifications
The Server-sent Events specification is an integral part of the HTML 5 specification. For more information about the specifications, see reference resources. This specification is relatively simple and mainly consists of two parts: the first part is the communication protocol between the server and the browser, and the second part is the EventSource object available for JavaScript on the browser side. Communication protocols are simple text-based protocols. The content type of the server-side response is "text/event-stream ". The content of the response text can be viewed as an event stream consisting of different events. Each event consists of two parts: type and data. Each event can have an optional identifier. The content of different events is separated by blank lines ("\ r \ n") that only contain carriage returns and line breaks. The data of each event may consist of multiple rows. Code List 1 provides an example of a server response:
retry: 10000\nevent: message\nid: 636307190866448426\ndata: 2017/05/18 15:44:46\n\n
Chrome browser monitoring view:
Response Message Header:
Response Message content:
Each event is separated by a blank line. For each row, the colon (":") indicates the type of the row, and the colon is followed by the corresponding value. Possible types include:
The type is blank, indicating that the row is a comment and will be ignored during processing.
The data type indicates that the row contains data. Rows starting with data can appear multiple times. All these rows are data of the event.
If the type is event, this row is used to declare the event type. When the browser receives the data, it will generate corresponding types of events.
The type is id, which indicates the identifier of the row used to declare the event.
The type is retry, indicating that this row is used to declare the waiting time before the browser connects again after the connection is closed.
When there are multiple rows of data, the actual data is connected by a line break.
If the data returned by the server contains the event identifier, the browser records the identifier of the last received event. If the connection to the server is interrupted, when the browser connects again, the identifier of the Last received Event is declared through the HTTP header "Last-Event-ID. The server can determine from which event to continue the connection by using the event identifier sent by the browser.
For the response returned by the server, the browser needs to use the EventSource object in JavaScript for processing. EventSource uses the standard event listener mode. You only need to add the corresponding event handling method to the object. EventSource provides three standard events:
Standard events provided by the EventSource object
Name Description event handling method
Open generates onopen when a connection is established successfully with the server.
Message: onmessage is generated when an event sent by the server is received.
An onerror occurs when an error occurs.
In addition, the server can return custom events. For these events, you can use the addEventListener method to add corresponding event handling methods:
Var es = new EventSource ('events'); es. onmessage = function (e) {console. log (e. data) ;}; // custom event myeventes. addEventListener ('myevent', function (e) {console. log (e. data );});
After an EventSource object is created for a specified URL, you can use the onmessage and addEventListener methods to add event handling methods. When a new event is generated on the server, the corresponding event processing method is called. The onmessage attribute of the EventSource object is similar to addEventListener ('message'). However, the onmessage attribute only supports one event processing method.
Traditional web pages use browsers to "query" data from servers. However, in many cases, the most effective method is to "send" data from servers to browsers. For example, when receiving a new email, the server sends a "notification" to the browser, which is more efficient than the browser's regular query to the server. Server-Sent Events (SSE) is a new API proposed to solve this problem, which is deployed on the EventSource object. Currently, all other mainstream browsers except IE are supported.
Simply put, the so-called SSE means that the browser sends an HTTP request to the server, and then the server continuously pushes "message" to the browser one way ). The format of this information is very simple, that is, "information" is prefixed with "data:" and ended with "\ n.
SSE and WebSocket have similar functions and are used to establish communication channels between browsers and servers. The difference between the two is:
WebSocket is a full-duplex channel that supports two-way communication and is more powerful. SSE is a one-way channel and can only be sent from the server to the browser.
WebSocket is a new protocol that requires server support. SSE is deployed on the HTTP protocol and is supported by existing server software.
SSE is a lightweight protocol, which is relatively simple; WebSocket is a heavier protocol, which is relatively complex.
SSE supports reconnection by default, and WebSocket requires additional deployment.
SSE supports Custom Data Types for sending.
From the comparison above, we can see that the two have their own characteristics and are suitable for different occasions.
The complete HTML5 page and C # (MVC implements the server code) are as follows:
Front-end HTML5 page:
<! DOCTYPE html>
C # Write Server:
Using System; using System. net. http; using System. text; using System. threading. tasks; using System. web. http; namespace WebTest. controllers {// <summary> // api/{controller}/{id} // </summary> public class MyAPIController: apiController {static readonly Random random = new Random (); // <summary> ///... api/MyAPI/ServerSentEvents // </summary> // <returns> </returns> [HttpGet, HttpPost] public Task <HttpResponseMessage> ServerSentEvents () {// Response. contentType = "text/event-stream" // Response. expires =-1 // Response. write ("data:" & now () // Response. flush () string data = ""; if (random. next (0, 10) % 3 = 0) {// wake up custom memevent data = ServerSentEventData ("this is a custom notification", DateTime. now. ticks. toString (), "CustomEvent");} else {// wake up the default message data = ServerSentEventData (DateTime. now. toString ("yyyy/MM/dd HH: mm: ss"), DateTime. now. ticks. toString ();} HttpResponseMessage response = new HttpResponseMessage {// Note: ContentType = "text/event-stream" Content = new StringContent (data, Encoding. getEncoding ("UTF-8"), "text/event-stream")}; return Task. fromResult (response);} public string ServerSentEventData (string data, string id, string _ event = "message", long retry = 10000) {StringBuilder sb = new StringBuilder (); sb. appendFormat ("retry: {0} \ n", retry); sb. appendFormat ("event: {0} \ n", _ event); sb. appendFormat ("id: {0} \ n", id); sb. appendFormat ("data: {0} \ n", data); return sb. toString ();}}}
Display result of communication on the page:
Monitoring Network interaction time series through Chrome:
Output through the Chrome console. The following is the details of a round of ope, message, and error events:
So far, the success is achieved.