For general web applications, most developers are no stranger. In web applications, the interactive mode of request/ response is used between the browser and the server. The browser issues a request, and the server generates the corresponding response according to the request. The browser is processed to the receiving response to users. The response format may be HTML, XML, or JSON. With the REST architecture style and the popularity of AJAX, the server uses JSON as a response data format more. The web application uses the XMLHTTPREQUEST object to send the request and dynamically update the content of the page according to the data returned by the server. Generally speaking, users' operations on the page, such as clicking or moving the mouse, will trigger the corresponding events. A request is issued by the XMLHTTPRequest object, and the page has a local update after the server responds. The deficiencies of this method are that the data generated by the server cannot be notified of the browser in time, but it needs to be obtained by the browser until the next request is sent. For some applications with high -time data requirements, this delay is unacceptable. In order to meet the needs of such applications, there is a need for some ways to push data from the server to the browser to ensure that the data changes on the server side can be notified to users at the first time. There are many common solutions, which can be divided into two categories. The difference between these two methods is whether it is based on the HTTP protocol. The practice of not using the HTTP protocol is to use the new WebSocket specifications of HTML 5, and the method of using the HTTP protocol includes simple rotation, COMET technology, and the HTML 5 server push event described in this article. These technologies will be introduced below.
Brief introductionBefore introducing the HTML 5 server push event, first introduce some of the number of server -side data push technology mentioned above. The first is WebSocket. The WebSocket specification is an important part of HTML 5. It has been supported by many mainstream browsers, and many applications developed based on WebSocket. Just as the name is expressed, WebSocket uses a jacket connection, based on the TCP protocol. After using WebSocket, it actually builds a set of word connections between the server and the browser, which can be transmitted in two -way data. The function of WebSocket is very powerful, and it is flexible to use, which can be suitable for different scenarios. However, WebSocket technology is also relatively complicated, including the implementation of the server and the browser side different from ordinary web applications.
Except for WebSocket, other implementation methods are based on the HTTP protocol to achieve the effect of real -time push. The first method is simple rotation, that is, the browser sends a request to the server from time to time to inquire whether there is data update. This approach is relatively simple and can solve the problem to a certain extent. However, carefully consider the time interval of rotation. If the interval between rotation is too long, it will cause users to not receive the updated data in time; the short interval between the rotation will cause too much query request and increase the burden on the server side.
COMET technology has improved the shortcomings of simple rotation, using long -wheeled inquiries. Each request for long rotation, the server will keep the connection in a period of opening for a period of time, rather than close it immediately after the response is completed. The advantage of this is that within the time period when the connection is opened, the data update generated by the server can be returned to the browser in time. When a long connection is closed, the browser will immediately open a new long connection to continue the request. However, the implementation of Comet technology requires the support of a third -party library on the server and the browser side. In summary comparison, the four different technologies mentioned above are not recommended for use due to their defects. Comet technology is not part of the HTML 5 standard. From the perspective of compatible standards, it is not recommended. WebSocket specifications and server push technology are part of the HTML 5 standard. It provides native support on the mainstream browser and is recommended to use. However, the WebSocket specifications are more complicated and are suitable for scenes that need to be complicated and two -way data communication. For simple server data push scenarios, it is enough to use server push events.
In terms of browser support, server push events have been supported on most desktops and mobile browsers except IE. The browsers and versions of the support server push event 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 andr andr OID 19.0+ and Blackberry Browser 7.0+ et al. The support of IE has a detailed introduction in the following chapters.
The following specifications of the server push event specification are specified.
specificationThe Server-SENT EVENTS specification is an integral part of the HTML 5 specification. For specific specifications, please refer to reference resources. This specification is relatively simple, mainly consisting of two parts: the first part is the communication protocol between the server and the browser side, and the second part is the EventSource object used by the browser to use JavaScript. The communication protocol is a simple protocol based on pure text. The content of the response on the server is Text/Event-Stream. The content of the response text can be regarded as an event flow, which is composed of different events. Each event consists of two parts: type and data, and each event can have an optional identifier. The content of different events is separated by the empty lines (/r/n) that only includes the car Enter and the royal symbol. The data of each event may be composed of multiple lines. Code list 1 gives an example of the server -side response.
Example of server -side responseData: First EventData: Second Eventid: 100event: MyEventData: Third Eventid: 101: This is a CommentData: Fouteh EventData: Fours Event Continue
As shown in List 1, each event is separated by an empty line. For each line, the colon (:) is the type of the line before, and the corresponding value behind the colon. Possible types include:
In the above code, the first event only contains data first event, which will generate default events; the identifier of the second event is 100, the data is Second Event; the third event will produce events with myEvent; the last one The data of the event is Fours Event/NFOUNTH EOVENT CONTINUE. When there are multiple lines of data, the actual data is connected by the data for the change of the line.
If the data returned by the server contains the identifier of the event, the browser will record the identifier of the recently received event. If the connection to the server is interrupted, when the browser end is connected again, the logo of the last time the event is obtained by the HTTP head-event-id. The server can be determined by the event identifier sent by the browser side to determine which event starts to continue connection.
For response returned by the server side, the browser side needs to use the EventSource object in JavaScript for processing. EventSource uses a standard event monitoring method, which only needs to add the corresponding event processing method to the object. EventSource provides three standard events, as shown in Table 1.
Table 1. Standard event provided by the EventSource object| name | illustrate | Event handling method |
| open | When the connection with the server is successfully established | onopen |
| Message | When the event sent by the server | onMessage |
| error | When an error occurs | onerror |
As mentioned earlier, the server can return a custom type event. For these events, you can use the AddeventListener method to add the corresponding event processing method. Code list 2 gives an example of the EventSource object.
Examples of the EventSource object var ES = New EventSource ('Events'); Es.onMessage = Function (E) {console.log (E.Data);}; ES.AdDeventListener ('Myevent', Function (E) {Console. Log (e. data);});As shown above, after creating the EventSource object specifically, the event processing method can be added through the OnMessage and AddeventListener methods. When the server has new events, the corresponding event processing method will be called. The role of the ONMESSAGE property of the EventSource object is similar to that of AddeventListener ('Message'), but the OnMessage attribute only supports one event processing method. After introducing the specification content of the server push event, the implementation of the server is introduced below.
The server and the browser end implementationIt can be seen from the description of the communication protocol in the previous section that the server push event is a simpler protocol. The implementation of the server side is relatively simple. Just return the response content in accordance with the format specified in the agreement. A variety of different server -side technology can be found in the open source community. It is not difficult to develop itself. This article uses Java as the implementation language of the server. Correspondingly implementing open source-based-Eventsource-Servlet project, see reference resources. The following is a specific example to illustrate how to use Jetty-Eventsource-Servlet project. The example is used to simulate the random movement of an object in a limited space. The object starts from a random position, and then randomly selects one direction from the top, bottom, left, and right directions, and moves a random distance in this direction. The server is constantly changing the position of the object and pushing the location information to the browser, which is displayed by the browser.
Server implementation服务器端的实现由两部分组成:一部分是用来产生数据的org.eclipse.jetty.servlets.EventSource 接口的实现,另一部分是作为浏览器访问端点的继承自org.eclipse.jetty.servlets.EventSourceServlet 类的Servlet implementation. The following code gives an implementation class of the EventSource interface.
EventSource interface implementation class MovementEventsource
Public Class MovementEventsource Implements eventSource {Private Int Width = 800; Private Int Height = 600; Private Int Stepmax = 5; Private Int x = 0 0 ; Private int y = 0; private random random = new rate (); private logger logger = logger .getLogger (getClass (). Getname ()); Public MovementEventsource (int Width, Int Height, int Stepmax) {this.width = width; this.Height = Hei ght; this.stepmax = stepmax; this.x = random.nextint (width); this.y = random.nextint (height);} @Override Public Void Onopen (Emitter Emitter) Throws IOEXCEPTION {Query (Emitter); Ride Public Void Onresume (Emitter Emitter, String Lasteventid) Throws IOEXception {UpdatePosition (Lasteventid); // Update the starting position query (emitter); // Start generate position information} // Update the starting position PRIVATE VOID Tion (string id) {if (ID! = Null) {string [] pos = id.split (,); if (pos.length> 1) {int xpos = -1, yPOS = -1; try {xpos = integer.parseint (POS [0 [0 ], 10); YPOS = Integer.parseint (POS [1], 10);} Catch (NumberFormatexception E) {} if (isValidmove (xpos, yPOS)) {x = xpos; }} PRIVATE Void Query (Emitter Emitter) Throws IOEXCEPTION {Emitter.comment (Start Sert Sending Movement Information.); While (true) {emitter.com (); // raing id = string.format (%s,%% s, x, y); emitter.id (id); // generate an event identifier emitter.data (ID) according to the location; // Send position information data try {thread.sleep (2000);} Catch (interruptedException E) {Logger.log (Level.warning, /Movement Query Thread Interrupted. Close the connection., e); break;}} emitter.close (); // Turn off the connection} public void onClose () {} // Get the next legitimate mobile location private void move () {while (true) {int [] move = getmove (); int xnext = x + move [0]; int ynext = y + move [1] ; if (ISVALIDMOVE (XNEXT, YNEXT)) {x = xnext; y = ynext; break;}} // Judging whether the current movement position is legal. rn x> = 0 && x <= width && y> = 0 && y <= height;} // Randomly generates the next mobile position private int [] getmove () {int [] xdir = new int }; int [] ydir = new int [] {0, -1, 0, 1}; int Dir = random.nextint (4); Return new int / ydir [dir] * random.nextint (stepmax)};}}The MovementEventsource needs to implement the ONOPEN, OnResume and OnClose method of the EventSource interface. The Onopen method is called when the browser is connected. Connected Uttales are called. Both the ONOPEN and OnResume methods have a parameter of the eventSource.emitter interface, which can be used to send data. The methods contained in the EventSource.emitter interface include Data, Event, Comment, ID, and Close, which correspond to various types of events in the communication protocol, respectively. The onResume method also contains an additional parameter Lasteventid, indicating the identifier of the latest event sent by the Last-Event-ID header.
The main logic of events generated in the event in the MovementEventSource class is in the Query method. This method contains an unlimited cycle that changes the position every 2 seconds, and at the same time send the updated position to the browser end through the data method of the update position through the data method of the EventSource.emitter interface. Each event has a corresponding identifier, and the value of the identifier is the position itself. If the browser is re -connected after the connection is disconnected, the object can be moved from the last position.
It is simple to implement the service of the service -corresponding to the MovementEventsource class. It only needs to inherit the newEventSource method from the EventSourceServlet class and cover it. In the implementation of the NewEventsource method, a MovementEventSource class needs to be returned, as shown below. Whenever the browser is established, the service creates an object of a new MovementEventSource class to handle the request.
Servlet implementation of MovementServlet Public Class MovementServlet EXTENDSARCESORCESERVLET {@Override ProteCted EventSource NewsSource (HTTPSERVLETREQUEST, String Clientid) Return New MovementEventsource (800, 600, 20);}}In the server implementation, it should be noted that the corresponding server filter support should be added. This is the requirement of the Jetty Continuations framework that the Jetty-EventSource-Servlet project relies on, otherwise there will be errors in the case. The method of adding a filter is to add the configuration content as shown below in the web.xml file.
The configuration of the service filter required by Jetty Continuations<filter> <filter-name> Continuation </Filter-name> <filter-class> org.eclipse.Jetty.Continuation.Continuationfilter </Filter-Class> </Filter> <Filter-MA pping> <filter-name> Continuation </filter-name> <url-Pattern>/SSE/*</url-Pattern> </Filter-Mapping>Browser end implementation
The implementation of the browser side is relatively simple. You only need to create an EventSource object and add the corresponding event processing method. The following code gives the corresponding implementation. Use a square on the page to represent an object. When a new event is received, the position of the block is on the page according to the coordinate information given in the event data.
Implementation code of the browser side 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 introducing the basic server side and browser ending, the more important IE support is introduced below.
IE supportA big problem 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 way is to use the original EventSource object on other browsers, while using simple rotation or COMET technology on IE; another method is to use Polyfill technology, even using the JavaScript library provided by a third party to block browsing browsing Different from the device. This article uses Polyfill technology, just loading a third -party JavaScript library on the page. Applying the browser side code does not need to be changed. It is generally recommended to use a second method, because in this way, only one implementation technology is required on the server side.
It is not easy to provide a similar primary EventSource object on IE. In theory, only the XMLHTTPRequest object is needed to obtain the response content of the server side, and through text analysis, the corresponding events can be extracted and the corresponding event processing method can be triggered. The problem is that the XMLHTTPREQUEST object on IE does not support the response content of the obtaining part. Only after the response is completed can it be obtained. Because the server push event uses a long connection. When the connection is always open, the corresponding event cannot be triggered through the XMLHTTPRequest object, and the corresponding event cannot be triggered. More specifically, when the ReadyState of the XMLHTTPREQUEST object is 3 (ReadyState_interactive), its Responsetext attribute cannot be obtained.
In order to solve the problem of XMLHTTPREQUEST objects on IE, you need to use the XDOMAINREQUEST object introduced in IE 8. The role of the XDOMAINREQUEST object is to send a cross -domain AJAX request. The XDOMAINREQUEST object provides the onProgress event. When the OnPROGress event occurs, some content of the response can be obtained through the ResponseText property. This is the biggest difference between the XDOMAINREQUEST object and the XMLHTTPRequest object. It is also the basis of using the XDOMAINREQUEST object to achieve a native EventSource object. After using the XDOMAINREQUEST object to open the connection to the server side, when the new data is generated on the server, it can be processed by the onProgress event of the XDOMAINREQUEST object. event.
However, due to the original purpose of the XDOMAINREQUEST object is to issue cross -domain AJAX requests. Considering the security issues of cross -domain access, the limitation of the XDOMAINREQUEST object is also strict when used. These restrictions will affect its implementation as an EventSource object. The specific restrictions and solutions are shown below:
Due to these restrictions on the XDOMAINREQUEST object, the implementation of the server also needs to make corresponding changes. These changes include returning the Access-Control-Allow-Origin head; analyze the parameters of the Text/PLAIN type sent by the browser; process information related to user certification contained in the request.
The Polyfill library used in this article is the EventSource project developed by Yaffle on Github. For the specific address, please refer to reference resources. After using the Polyfill library and modifying the implementation of the server side, you can use the server to push the event in the browser IE 8 and above. If you need to support IE 7, you can only use simple inquiry or COMET technology. See reference resources in the example code of this article.
summaryIf you need to push the data from the server to the browser, the technologies that can be used based on the HTML 5 specification standards include WebSocket and server push events. Developers can choose the right technology according to the specific needs of the application. If you only need to push data from the server, the standard of the server push event is simpler and easier to achieve. This article has introduced the standard content of the server push event, the implementation of the server and the browser side in detail, and also analyzed how to support the IE browser.