HTML5 Server Push events (server-sent events) Combat development

Source: Internet
Author: User
Tags event listener session id

Transferred from: http://www.ibm.com/developerworks/cn/web/1307_chengfu_serversentevent/

http://www.ibm.com/developerworks/cn/web/wa-lo-comet/--comet Long Connection

Server Push events (server-sent events) is an integral part of the HTML 5 specification that can be used to push data from the service side in real time to the browser side. Compared to the similar COMET and WebSocket technologies, Server push events are easier to use and have less server-side changes. Server push events are the best choice for some types of applications. In this paper, the server push technology is described in detail, including the browser side and the server side of the corresponding implementation details, for the use of this technology in practice provides a guide.

    • Content
      • Brief introduction
      • Specification
      • Server-side and browser-side implementations
      • IE Support
      • Summary
      • Resources
      • Comments

Develop and deploy your next application on the IBM Bluemix cloud platform.

Get started with your trial

For general WEB application development, most developers are not unfamiliar. In a WEB application, a request/response interaction pattern is used between the browser and the server. The browser makes the request and the server generates the corresponding response based on the request received. The browser then processes the received response and presents it to the user. The format of the response may be HTML, XML, or JSON. With the REST architecture style and the popularity of AJAX, the server uses JSON more in response to the data format. The Web app uses the XMLHttpRequest object to send requests and dynamically update the contents of the page based on the data returned from the server side. Typically, a user's actions on a page, such as clicking or moving the mouse, trigger the corresponding event. A local update of the page is made by the XMLHttpRequest object to make the request and get a response from the server. The disadvantage of this approach is that the data generated by the server will not be able to notify the browser in a timely manner, but will need to wait until the next request is issued to be retrieved by the browser. This delay is unacceptable for some applications that require a high level of real-time data.

To meet the needs of such applications, there is a need to be able to push data from the server side to the browser to ensure that data changes on the server side can be notified to the user at the first time. There are a number of common solutions, which can be divided into two main categories. The difference between these two types of methods is whether they are implemented based on the HTTP protocol. The practice of not using the HTTP protocol is to use the new WebSocket specification in HTML 5, while the use of the HTTP protocol includes simple polling, COMET technology, and the HTML 5 server push events described in this article. These techniques are described below.

Brief introduction

Before introducing the HTML 5 Server push event, let's start by introducing some of the server-side data push technologies mentioned above. The first kind is WebSocket. WebSocket specification is an important part of HTML 5, has been supported by many mainstream browsers, there are many applications based on WebSocket development. As the name indicates, WebSocket uses a socket connection, based on the TCP protocol. After using WebSocket, a socket connection is actually established between the server side and the browser, which enables two-way data transfer. The WebSocket features are powerful, flexible to use and can be used in different scenarios. However, WebSocket technology is also more complex, including server-side and browser-side implementations are different from the general Web applications.

In addition to WebSocket, the other implementation is based on the HTTP protocol to achieve real-time push effect. The first is a simple poll, where the browser is timed to make a request to the server to query for data updates. This approach is relatively simple and can be solved to some extent. However, the time interval for polling needs to be carefully considered. The polling interval is too long, which causes the user to not receive the updated data in time, and the polling interval is too short, resulting in too many query requests and increasing the burden on the server side.

COMET technology improves the disadvantage of simple polling by using long polling. The long polling method on each request, the server side keeps the connection open for a period of time, rather than shutting down immediately after the response is completed. The advantage of this is that the data updates generated by the server can be returned to the browser in a timely manner during the time the connection is open. When the last long connection is closed, the browser will immediately open a new long connection to continue the request. However, the implementation of COMET technology requires third-party library support both on the server side and on the browser side.

In a comprehensive comparison of the 4 different technologies mentioned above, simple polling is not recommended due to its own shortcomings. COMET technology is not part of the HTML 5 standard and is not recommended from a standards-compliant perspective. The WebSocket specification and server Push technology are all part of the HTML 5 standard and are recommended for native support on mainstream browsers. However, the WebSocket specification is more complex and is suitable for scenarios where complex bidirectional data communication is required. For simple server data push scenarios, using server push events is sufficient.

In terms of browser support, server push events have been supported on most desktop and mobile browsers except IE. Browsers and versions that support server push events include: Firefox 6.0+, Chrome 6.0+, Safari 5.0+, opera 11.0+, IOS Safari 4.0+, opera Mobile 11.1+, Chrome for Android 25.0+, Firefox for Android 19.0+ and Blackberry Browser 7.0+. Support for IE is described in detail in the following sections.

The following is a specific description of the server push event specification.

Back to top of page

Specification

The Server-sent Events specification is an integral part of the HTML 5 specification, which is referenced in the specific specification documentation. The specification is simple and consists of two parts: the first part is the communication protocol between the server side and the browser side, and the second part is the EventSource object that is available to JavaScript in the browser side. A communication protocol is a simple protocol based on plain text. The content type of the server-side response is "Text/event-stream". The content of the response text can be thought of as an event stream, composed of different events. Each event consists of a two-part type and data, and each event can have an optional identifier. The contents of different events are separated by a blank line containing only carriage returns and line breaks ("\ r \ n"). The data for each event may consist of multiple lines. Code Listing 1 shows an example of a server-side response.

Listing 1. Example of server-side response
Data:first Eventdata:second Eventid:100event:myeventdata:third Eventid:101:this is a commentdata:fourth eventdata: Fourth event continue

As shown in Listing 1, each event is delimited by a blank line. For each line, the colon (":") is preceded by the type of the row, and the corresponding value is followed by the colon. Possible types include the following:

    • The type is blank, indicating that the row is a comment and is ignored when processing.
    • The type is data, which means that the row contains the information. Rows beginning with data can appear more than once. All these rows are the data for the event.
    • Type is an event that represents the type that the row uses to declare the event. When the browser receives the data, it produces the corresponding type of event.
    • The type is an ID that represents the identifier that the row uses to declare the event.
    • The type is retry, which means that the row is used to declare the browser's wait time before connecting again after the connection is broken.

In code Listing 1, the first event contains only the data "primary event", the default event is generated, the second event has an identifier of 100, the data is "second event", and the third event produces an event of type "MyEvent"; the data for the last event is " Fourth Event\nfourth event Continue ". When there is more than one row of data, the actual data is concatenated with a newline character for each row of data.

If the data returned by the server side contains an identifier for the event, the browser records the identifier of the most recently received event. If the connection to the server is interrupted, when the browser side connects again, the identifier of the last received event is declared through the HTTP header "Last-event-id". The server side can determine from which event to continue the connection by the event identifier sent by the browser side.

For the response returned by the server side, the browser side needs to use the EventSource object in JavaScript for processing. EventSource uses the standard event listener approach, just add the appropriate event handling method to the object. EventSource provides three standard events, as shown in table 1.

Table 1. Standard events provided by the EventSource object
name Description Event Handling Methods
Open Generated when a connection to the server is successfully established OnOpen
Message Occurs when an event sent by the server is received OnMessage
Error Generated when an error occurs OnError

As mentioned earlier, the server side can return events of a custom type. For these events, you can use the AddEventListener method to add an appropriate event-handling method. Code Listing 2 shows an example of using the EventSource object.

Listing 2. Examples of using EventSource objects
var es = new EventSource (' Events '); es.onmessage = function (e) {    console.log (e.data);}; Es.addeventlistener (' MyEvent ', function (e) {    console.log (e.data);});

As shown in Listing 2, after you have created the EventSource object at the specified URL, you can add an event-handling method through the OnMessage and AddEventListener methods. When a new event is generated on the server side, the corresponding event handling method is called. The OnMessage property of the EventSource object acts like AddEventListener (' message '), but the OnMessage property supports only one event-handling method.

Following the specification of the server push event, the server-side implementation is described below.

Back to top of page

Server-side and browser-side implementations

As can be seen from the description of the communication protocol in the previous section, server-side push events are a relatively simple protocol. Server-side implementation is relatively simple, just in accordance with the protocol specified in the format, the response content can be returned. The open source community can find a variety of different server-side technologies corresponding to the implementation. It is not very difficult to develop yourself. This article uses Java as the server-side implementation language. The corresponding implementation is based on the open source Jetty-eventsource-servlet project, see Reference Resources. The following is a concrete example of how to use the Jetty-eventsource-servlet project. Examples are used to simulate the random movement of an object in a confined space. The object starts at a random position, and then randomly selects a direction from the top, bottom, left, and right four directions and moves the random distance in that direction. The server side constantly changes the position of the object and pushes the location information to the browser, which is displayed by the browser.

Server-side implementation

The server-side implementation consists of two parts: the implementation of the Org.eclipse.jetty.servlets.EventSource interface used to generate the data, and the other part is the inheritance from the browser access endpoint The servlet implementation of the Org.eclipse.jetty.servlets.EventSourceServlet class. Code Listing 3 shows the implementation class for the EventSource interface.

Listing 3. Implementation class of EventSource interface Movementeventsource
 public class Movementeventsource implements EventSource {private int width = 800;private int height = 600;private int ste PMax = 5;private int x = 0;private int y = 0;private random random = new random ();p rivate Logger Logger = Logger.getlogger (GetClass (). GetName ());p ublic movementeventsource (int width, int height, int stepmax) {this.width = Width;this.height = h Eight;this.stepmax = Stepmax;this.x = Random.nextint (width); this.y = random.nextint (height);} @Overridepublic void OnOpen (Emitter Emitter) throws IOException {query (Emitter);//Start generating location information} @Overridepublic void Onresume (Emitter Emitter, String lasteventid) throws IOException {updateposition (Lasteventid);//update starting position query (Emitter)  ; Start generating location Information}//Update the starting position according to Last-event-id private void updateposition (String id) {if (id! = NULL) {string[] pos = Id.split (","); if (Pos.length > 1) {int xPos =-1, YPos = -1;try {XPos = Integer.parseint (Pos[0], ten); YPos = Integer.parseint (Pos[1], 10);} catch (NumberFormatException e) {}if (Isvalidmove (XPos, YPos){x = Xpos;y = YPos;}}}} private void query (Emitter Emitter) throws IOException {emitter.comment ("Start Sending movement information."); while (true) {emitter.comment (""); Move (); Move position String id = String.Format ("%s,%s", X, y); emitter.id (ID); Generates event identifier Emitter.data (ID) based on location; Send location information data try {Thread.Sleep (c);} catch (Interruptedexception e) {logger.log (level.warning, "movement que Ry thread interrupted. Close the connection. ", e); break;}} Emitter.close (); When the loop terminates, close the connection} @Overridepublic void OnClose () {}//Gets the next legitimate move position private void move () {while (true) {int[] move = Getmove (); T xnext = x + move[0];int Ynext = y + move[1];if (isvalidmove (Xnext, Ynext)) {x = Xnext;y = Ynext;break;}}} Determines whether the current moving position is legal private Boolean isvalidmove (int x, int y) {return x >= 0 && x <= width && y >=0 &A mp;& y <= height;} Randomly generate next move location private int[] Getmove () {int[] Xdir = new int[] {-1, 0, 1, 0};int[] Ydir = new int[] {0,-1, 0, 1};int dir = Random.nextint (4); return new int[]{Xdir[dir] * Random.nextint (Stepmax), Ydir[dir] * Random.nextint (Stepmax)};}} 

In Listing 3, the class Movementeventsource needs to implement the OnOpen, Onresume, and OnClose methods of the EventSource interface, where the OnOpen method is called when the browser-side connection is opened, and the Onresume method The browser is called when the connection is re-established, and the OnClose method is called when the browser closes the connection. Both the OnOpen and Onresume methods have an Eventsource.emitter interface type parameter that can be used to send data. The methods included in the Eventsource.emitter interface include data, event, comment, ID, and close, respectively, corresponding to the various types of events in the communication protocol. The Onresume method also contains an additional parameter, Lasteventid, that represents the identifier of the most recent event sent over Last-event-id hair.

The primary logic for event generation in the Movementeventsource class is in the Query method. The method contains an infinite loop, changing the position every 2 seconds, and sending the updated position to the browser via the data method of the Eventsource.emitter interface. Each event has a corresponding identifier, and the value of the identifier is the location itself. If the connection is broken and the browser is reconnected, you can continue moving the object from the last position.

The servlet implementation corresponding to the Movementeventsource class is relatively simple, just inherit from the Eventsourceservlet class and overwrite the Neweventsource method. In the implementation of the Neweventsource method, you need to return an object of the Movementeventsource class, as shown in Listing 4. Whenever a connection is established on the browser side, the servlet creates a new object of the Movementeventsource class to handle the request.

Listing 4. Servlet Implementation Class Movementservlet
public class Movementservlet extends Eventsourceservlet {  @Override  protected EventSource neweventsource ( HttpServletRequest request,  String clientId) {  return new Movementeventsource (+);  }  }

In a server-side implementation, it is important to note that the appropriate servlet filter support is added. This is the requirement of the jetty continuations framework that the Jetty-eventsource-servlet project relies on, otherwise there will be an error. The way to add a filter is to add the configuration shown in Listing 5 in the Web. xml file.

Listing 5. Configuration of the servlet filter required by the Jetty continuations
<filter>     <filter-name>continuation</filter-name>     <filter-class> org.eclipse.jetty.continuation.continuationfilter</filter-class>  </filter>  < filter-mapping>     <filter-name>continuation</filter-name>     <url-pattern>/sse/*< /url-pattern>  </filter-mapping>
Browser-side implementation

Browser-side implementation is also relatively simple, only need to create a EventSource object, and add the appropriate event handling methods. Code Listing 6 shows the corresponding implementation. Use a block in the page to represent the object. When a new event is received, the position of the block on the page is updated based on the coordinate information given in the event data.

Listing 6. Browser-side Implementation code
var es = new EventSource (' sse/movement ');  Es.addeventlistener (' message ', function (e) {      var pos = e.data.split (', '), x = Pos[0], y = pos[1];      $ (' #box '). css ({          left:x + ' px ',          top:y + ' px ');      });

After the introduction of the basic server-side and browser-side implementations, the following describes the more important IE support.

Back to top of page

IE Support

One of the big problems with using the browser's native EventSource object is that IE does not provide support. In order to provide the same support on IE, there are generally two ways. The first approach is to use native EventSource objects on other browsers, while using simple polling or COMET technology on IE, or using Polyfill technology, which uses JavaScript libraries provided by third parties to mask the differences between browsers. This article uses the Polyfill technology to load third-party JavaScript libraries on the page only. The browser-side code of the app itself does not need to be changed. It is generally recommended to use the second approach, because in this case, only one implementation technique is required on the server side.

It is not easy to provide an implementation similar to native EventSource objects on IE. Theoretically, only through the XMLHttpRequest object to obtain the server-side response content, and through text parsing, you can extract the corresponding event, and trigger the corresponding event processing method. However, the problem is that the XMLHttpRequest object on IE does not support getting part of the response content. The content can only be obtained after the response has been completed. Because the server-side push event uses a long connection. When the connection is open, the XMLHttpRequest object does not get the content of the response, and the corresponding event cannot be triggered. More specifically, when the XMLHttpRequest object has a readyState of 3 (readystate_interactive), its responsetext attribute is not available.

In order to solve the problem of XMLHttpRequest object on IE, we need to use the Xdomainrequest object introduced in IE 8. The purpose of the Xdomainrequest object is to emit a cross-domain AJAX request. The Xdomainrequest object provides the OnProgress event. When the OnProgress event occurs, it is possible to obtain a portion of the response through the ResponseText property. This is the largest difference between the Xdomainrequest object and the XMLHttpRequest object, and is the basis for using Xdomainrequest objects to implement similar native EventSource objects. After using the Xdomainrequest object to open the connection to the server side, when the server side has the new data generation, can be processed by the Xdomainrequest object's OnProgress Event processing method, the data received to parse, Triggers the corresponding event based on the contents of the data.

However, because the Xdomainrequest object is intended to issue cross-domain AJAX requests, the Xdomainrequest object is more restrictive when used in the case of cross-domain access security. These restrictions affect how they are implemented as EventSource objects. The specific limitations and workarounds are as follows:

    • The server-side response needs to include the Access-control-allow-origin header, which declares which domains are allowed to access the URL. "*" indicates that access is allowed from any domain and is not recommended for use. Generally use the same domain as the current application, restricting access only from the current domain.
    • A request made by a Xdomainrequest object cannot contain a custom HTTP header, which restricts the identifier of the last event received by the browser to be declared using the Last-event-id header. This identifier can be passed only through an HTTP request, such as a GET request parameter or the content body of a POST request.
    • The requested content type (Content-type) of the Xdomainrequest object can only be "Text/plain". This means that when using a POST request, a framework used by the server side, such as a servlet, does not automatically parse the contents of the POST request and cannot use the GetParameter method of the HttpServletRequest class to obtain the contents of the POST request. The original request content can only be parsed on the server side, and the values of the parameters are obtained.
    • The request made by the Xdomainrequest object does not contain any information related to user authentication, including cookies. This means that if authentication is required on the server side, the user's authentication information, such as the session ID, needs to be passed through the HTTP request in other ways.

Due to these limitations of the Xdomainrequest object, the server-side implementation also needs to be changed accordingly. These changes include returning Access-control-allow-origin headers, parsing parameters for the type of "Text/plain" sent by the browser, and processing information about the user authentication contained in the request.

The Polyfill library used in this article is the EventSource project developed by Yaffle on GitHub, and the specific address is referenced in resources. After using the Polyfill library and modifying the server-side implementation, the server push event can be used in IE 8 and above. If you need to support IE 7, you can only use simple polling or COMET technology. The sample code for this article is shown in reference resources.

Back to top of page

Summary

If you need to push data from the server side to the browser, you can use techniques based on the HTML 5 specification, including WebSocket and server push events. Developers can choose the right technology based on the specific needs of the application. If you just need to push data from the server side, the server push event specification is simpler and easier to implement. In this paper, the specification content of Server push event, server-side and browser-side implementation are introduced in detail, and how to support IE browser is also analyzed concretely.

Reference Learning
    • Learn the specifics of the server Push event specification (server-sent events).
    • Learn more about the Jetty-eventsource-servlet project and the Jettycontinuations framework.
    • Learn about the XMLHttpRequest and Xdomainrequest objects on IE, and learn about the usage limitations of Xdomainrequest objects.
    • View details of the Polyfill Library of EventSource objects that support IE.
    • Review the sample code for this article.
    • DeveloperWorks Web Development Zone: Extend your skills in web development with articles and tutorials dedicated to web technology.
    • DeveloperWorks Ajax Resource Center: This is a one-stop center for information about AJAX programming models, including many documents, tutorials, forums, blogs, wikis, and news. Any new Ajax information can be found here.
    • The DeveloperWorks Web 2.0 Resource Center, a one-stop Center for Web 2.0-related information, includes a large number of Web 2.0 technical articles, tutorials, downloads, and related technical resources. You can also quickly learn about the concepts of Web 2.0 through the Web 2.0 starter section.
    • Check out the HTML5 topic for more information and trends related to HTML5.
Discuss
    • Join DeveloperWorks Chinese community. View developer-driven blogs, forums, groups, and wikis, and communicate with other DeveloperWorks users.

HTML5 Server Push events (server-sent events) Combat development

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.