HTML5 in the SSE (server push)

This article was originally Links: https://cloud.tencent.com/developer/article/1194063

SSE technology explain: a new HTML5 event server push technology

Foreword

In general, Web terminal instant messaging technology design constraints due to limited browser, has been not easy to implement, end mainstream Web instant messaging programs are basically four kinds: traditional Ajax polling short, Comet technology, WebSocket technology , SSE (Server-sent Events) . Technical strengths and weaknesses of these four ways, refer to the " Web instant messaging technology end inventory: short polling, Comet, Websocket, SSE ." This article will be devoted SSE technology.

Server push event (Server-sent Events), referred to as SSE, is an integral part of the HTML 5 specification can be used to push data in real time from the server to the browser. Similarly with respect to the COMET and WebSocket technology, the use of server push event easier, changes to the server side is relatively small. For some types of applications, server push event is the best option.

In this paper, server push (SSE) has been described in detail, it contains the corresponding implementation details browser-side and server-side, provides guidance for the use of the technology in practice. (This article published in sync: http://www.52im.net/thread-335-1-1.html )

 

Outline

For the average Web application development, most developers are not familiar with. In Web applications, used between the browser and server interactive mode request / response. Browser makes a request, the server generates a corresponding response according to the received request. The browser then processes the received response, presented to the user. Response format may be such as HTML, XML or JSON. With the popularity of AJAX and REST architectural style, the server greater use of JSON as a data format of the response. Web applications transmit a request to use the XMLHttpRequest object, and the data returned by the server, the content page is dynamically updated. In general, users operate on the page, such as clicking or moving the mouse will trigger the corresponding event. After partial page update request by the XMLHttpRequest object to obtain the server response. Disadvantage of this approach is that: a server-side data changes can not be produced promptly inform the browser, but need to wait until the next time the request is made in order to be acquired browser. For some high real-time requirements for data applications, this delay is unacceptable.

In order to meet the needs of such applications, we need to have some way to be able to push data from the server to the browser, in order to ensure that data changes on the server side can notify the user the first time. Currently, there are many common solution, it can be mainly divided into two categories. The difference between these two methods is whether to implement based on the HTTP protocol. Do not use the HTTP protocol approach is to use the new HTML 5 WebSocket specification, and the practice of using the HTTP protocol including improvised polling, HTML 5 COMET server technology and this article will introduce push event. Below these types of technologies will be introduced.

basic introduction

Before the introduction of HTML 5 server-push event (SSE technology), introduces some of the several server-side push technology data mentioned above.

The first is WebSocket. WebSocket specification is an important part of HTML 5, has been supported by many mainstream browsers, there are many applications based WebSocket development. As the name implies, like, WebSocket using a socket connection, based on the TCP protocol. After using a WebSocket, actually establish a socket connection between the server and the browser, bidirectional data transmission can be performed. WebSocket functionality is very powerful, flexible to use also can be applied to different scenarios. But WebSocket technology is more complex, including server and browser are realized from a general Web application. And there is even more unfortunate is WebSocket browser compatibility issues, like other newer technologies, like Web end, fortunately relatively mature packaging options to address this technical limitations, such as: open source Socket.io, see " the Socket. IO description: support WebSocket, instant messaging framework for the WEB end . "

In addition to WebSocket, other implementations are to achieve real-time push effect based on the HTTP protocol. The first approach is a simple polling, i.e., the timing of the browser request to the server, to check whether there is data update. This approach is relatively simple, can solve the problem to some extent. But for polling intervals need to be carefully considered. The polling interval is too long, the user can cause the received data can not be timely updated; polling interval is too short, a query request will cause excessive increase in the burden on the server side.

Comet technology to improve the shortcomings of simple polling (see: Comet technology explain: Web-based real-time communication terminal connected to a HTTP long ), using a long polling. Long polling manner with each request, the server will keep the connection open for a period of time, rather than immediately closed after the response is complete. The advantage of this is that the connection period is open, the data generated by the server-side update can be promptly returned to the browser. After a long connection is closed, the browser immediately opens a new long connection request to continue. However, achieve COMET technology on the server side and the browser will need the support of third-party libraries.

Comprehensive comparison of the above-mentioned four different techniques, simple polling due to defects of its own, is not recommended. Comet technology is not part of the HTML 5 standard, compatible with standard from the point of view, it is not recommended. WebSocket specification and server push is part of HTML 5 standard in the mainstream browsers provide native support, is recommended. But WebSocket specification more complicated for the need for two-way data communication of complex scenes. For simple server data push scenario, use server push (SSE technology) event is sufficient.

In support of the browser, server push event (SSE technology) has been supported on most desktop and mobile browsers except IE's. Supports server push event browser and its version 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+ and so on. IE on the support, there are described in detail in the following sections.

The following specification for server push event (SSE technology) will be specifically described.

And comparison of WebSocket

Simply do not say, SSE is suitable for frequent updates, low latency and data are from service to client.

It WebSocket difference:

Convenient, do not need to add any new components, with the back-end languages ​​and frameworks will be able to continue to use any habit, do not get a new IP or a new port number for the new virtual machine and bother.

Server-side simplicity. Because the SSE can operate on existing HTTP / HTTPS protocol, so it can run directly on the existing proxy server and authentication technologies.

WebSocket compared SSE biggest advantage is that it is two-way communication, which means that the server sends data as simple as receiving data from the server, while the SSE general by a separate Ajax request to transfer data from the client to the server, so the relative WebSocket use Ajax will increase overhead. Thus, if necessary to once per second or faster frequency data transmission to the server, you should use WebSocket.

SSE (Server-sent Events) in the specification and defined in HTML 5

Server-sent Events specification is an integral part of the HTML 5 specification, specific specification document, see Resources. This specification is relatively simple, mainly consists of two parts: The first part is a communication protocol between the server and the browser, the second part is used for an EventSource JavaScript on the browser side. Communication protocol is a simple protocol based on plain text. Content type of the response of the server is "text / event-stream". The text content of the response can be viewed as a stream of events, events of different composition. Each event type, and data from the two parts, and each event can have an optional identifier. We are separated by only a carriage return and linefeed comprising blank lines ( "\ r \ n") between the content of different events. Each event data may consist of multiple lines. Listing 1 shows an example of the server response.

Example Listing 1. The server response:

data: first event data: second event id: 100 event: myevent data: third event id: 101 : this is a comment data: fourth event data: fourth event continue

As shown in Listing 1, are separated by a blank line between each event. For each line, a colon ( ":") indicates the type of the front row, after the colon is the corresponding value. Possible types include:

Type is blank, indicating that the line is a comment and will be ignored during processing.

Type data, indicating that the line contains data. Lines beginning with data can appear multiple times. All these lines are the data of the event.

Type of event, said the bank is used to declare the type of event. When the browser receives the data, it will generate the corresponding types of events.

Type id, said the bank identifier used to declare an event.

Type retry, said the bank is used to declare browser waiting time before a connection again after disconnection.

In Listing 1, the first event data only contains "first event", the default event is generated; a second event identifier 100, the data for the "second event"; the third type of event will occur " myevent "event; data of the last event for the" fourth event \ nfourth event continue ". When multiple rows of data, the actual data is formed by a newline connecting each row of data.

If the data returned by the server contains the identifier of an event, the browser records the identifier of the last received event. If the connection to the server is interrupted when the browser to connect again, will be declared identifier last received events via HTTP header "Last-Event-ID". The server can determine which event from the beginning to continue the event through a connection identifier sent by the browser.

The server returns a response, the browser needs to be processed using an EventSource in JavaScript. EventSource using the standard event listener mode, just add the appropriate event handler method to on the object. EventSource provides three standard events, as shown in Table 1.

Table 1. EventSource standard event object provides:

As previously described, the server can return a custom type of event. For these events, you can add the corresponding event-handling method using addEventListener method. Listing 2 shows an example of the use of an EventSource.

Example Listing 2. EventSource object:

vares =newEventSource('events'); es.onmessage =function(e) { console.log(e.data); }; es.addEventListener('myevent',function(e) { console.log(e.data); });

As shown in Listing 2, after a specified URL EventSource create objects, you can add an event handler method by onmessage and addEventListener method. When the server side there is a new event occurs, the corresponding event handler method is called. Onmessage role EventSource object attributes similar to addEventListener ( 'message'), but onmessage property supports only one event handling method.

After the introduction to the normative content of server push event, the following server-side presentation.

SSE practical example: server and browser-side implementation

From a description of the protocol can be seen, the server-side push event is a relatively simple protocol. A server-side is also relatively simple, only in accordance with the format prescribed protocol, returns a response to the content. You can find a variety of server-side technology in the open source community corresponding implementation. The difficulty of developing its own is not large. As used herein, a server-side Java as the implementation language. Based on the corresponding open source jetty-eventsource-servlet project, see Resources. Below with a specific example to illustrate how to use the jetty-eventsource-servlet program. For example a pseudo random moving object in a defined space. The object starting from a random position, then randomly select a direction from the upper, lower, left and right directions, the movement and the distance in a random direction. Server-side changing position of the object, and the position to push information to the browser, is displayed by the browser.

1) The server-side implementation

The server is implemented by two parts: one is used to generate the data interface implemented org.eclipse.jetty.servlets.EventSource, the other is as a browser to access the endpoint inherited from class org.eclipse.jetty.servlets.EventSourceServlet servlet implementation. Listing 3 shows the implementation class EventSource interface.

Listing 3. EventSource interface implementation class MovementEventSource:

publicclassMovementEventSourceimplementsEventSource { privateintwidth =800; privateintheight =600; privateintstepMax =5; privateintx =0; privateinty =0; privateRandom random =newRandom(); privateLogger logger = Logger.getLogger(getClass().getName()); publicMovementEventSource(intwidth,intheight,intstepMax) { this.width = width; this.height = height; this.stepMax = stepMax; this.x = random.nextInt(width); this.y = random.nextInt(height); }

@Override publicvoidonOpen (Emitter emitter) throwsIOException {query (emitter); // start position information generating}

@Override publicvoidonResume (Emitter emitter, String lastEventId) throwsIOException {updatePosition (lastEventId); // start position update query (emitter); // start position information generating}

//根据Last-Event-Id来更新起始位置 privatevoidupdatePosition(String id) { if(id !=null) { String[] pos = id.split(","); if(pos.length >1) { intxPos = -1, yPos = -1; try{ xPos = Integer.parseInt(pos[0],10); yPos = Integer.parseInt(pos[1],10); }catch(NumberFormatException e) { }

(Jane book format can not work code, detailed code, see: http: //www.52im.net/thread-335-1-1.html)

Listing 3, the class MovementEventSource need to implement EventSource interface onOpen, onResume and onClose method in which onOpen method is called in the browser's connection open time, onResume method to re-establish the call when connected to the browser, onClose method at the browser closes the connection when they were called. and a method has onOpen onResume EventSource.Emitter interface type parameters, can be used to transmit data. The method comprises EventSource.Emitter contained in the interface data, event, comment, id and close the like, corresponding to various communication protocols different types of events. The onResume process additionally includes a parameter lastEventId, an identifier representing an event recently sent over by Last-Event-ID header.

The main event class logic MovementEventSource query generated in the process. The method comprises an infinite loop, once every two seconds to change the position, while the position after the update is sent to the browser by a method EventSource.Emitter data interface. Each event has a corresponding identifier, and the value of the identifier is the location itself. If after disconnection, reconnect the browser can continue to move the object starts from the last position.

Implementation and MovementEventSource class corresponding servlet is relatively simple, only need to inherit from EventSourceServlet newEventSource class and override the method can be. NewEventSource implementing the method, the need to return MovementEventSource object class, as shown in Listing 4. Whenever the browser to establish a connection, the servlet creates a new object MovementEventSource class to handle the request.

Listing 4. servlet implementation class MovementServlet:

publicclassMovementServletextendsEventSourceServlet { @Override protectedEventSource newEventSource(HttpServletRequest request, String clientId) { returnnewMovementEventSource(800,600,20); }

}

In the server-side implementation, note is to add the corresponding servlet filter support. This is a requirement Jetty Continuations framework of the jetty-eventsource-servlet project depends, otherwise error. Add filter is to add the contents of the configuration shown in Listing 5 web.xml file.

Listing 5. Jetty Continuations desired configuration servlet filter:

(Jane book format can not work code, detailed code, see: http: //www.52im.net/thread-335-1-1.html)

2) the browser-side implementation

Realization browser is relatively simple, only you need to create an EventSource, and add the appropriate event handlers can be. Listing 6 shows a corresponding realization. Use a square represents an object on the page. Upon receiving the new event, according to the coordinate information given in the event data, updating the position of a block on the page.

Listing 6. The browser-side implementation code:

(Jane book format can not work code, detailed code, see: http: //www.52im.net/thread-335-1-1.html)

After the introduction to the basic browser and server-side implementation, here are the more important support of IE.

IE compatibility problems

A big problem using the browser native EventSource object is IE does not provide support. In order to provide the same support in IE, there are two general ways. The first approach is to use other browsers native EventSource object, using a simple polling IE in the art or COMET achieved; Another approach is to use polyfill technique, i.e. using JavaScript libraries provided by third parties shielding browse different filter. As used herein, polyfill technology, only need to load a third-party JavaScript library to the page. The application itself does not require browser-side code to make changes. It is recommended to use the second approach, because in that case, only need to use a technique that can be realized on the server side.

EventSource provide similar original object is not simple to achieve in the IE. In theory, only to get a response by the content server XMLHttpRequest object, by parsing the text, can extract the corresponding event, and trigger the corresponding event processing method. But the problem is on the IE XMLHttpRequest object does not support the content portion of the fetch response. Only after the response is complete, in order to obtain its contents. Because the server push event using a long connection. When the connection remains open, and the content of the response can not be obtained through the XMLHttpRequest object, which corresponds to the event can not be triggered. More specifically, when readyState XMLHttpRequest object to 3 (READYSTATE_INTERACTIVE), which is responseText property can not be obtained.

In order to solve the problem IE XMLHttpRequest object, we need to use the object IE 8 XDomainRequest introduced. Effect object is an AJAX XDomainRequest cross-domain request. XDomainRequest object provides onprogress event. When onprogress event occurs, you may be obtained by partial response content responseText property. This is the biggest difference XDomainRequest object and the XMLHttpRequest object, but also a basis similar to the native EventSource object using XDomainRequest object. After use XDomainRequest object to open connections to the server when the server has new data is generated, can be processed by the processing method onprogress event XDomainRequest object, the received data is parsed trigger the corresponding content data is event.

However, because the original purpose XDomainRequest target is to issue cross-domain AJAX requests, taking into account the security issues of cross-domain access restrictions XDomainRequest object when using the more stringent. These restrictions will affect its implementation as EventSource object. Specific limitations and solutions are as follows:

Server's response needs to contain Access-Control-Allow-Origin header, used to declare which allow access to the URL from the domain. "*" Indicates to allow access from any domain, it is not recommended to use this value. Usually the current application using the same domain, only allow access from the current domain.

XDomainRequest object to issue a request can not contain custom HTTP header, which limits the identifier can not use the event Last-Event-ID statement browser up once recently received the. The contents thereof can only be transmitted identifier, such as a GET request or a POST request parameter otherwise HTTP request.

Content type (Content-Type) XDomainRequest requested object can only be "text / plain". This means that, when using the POST request, the server uses the frame, such as the servlet, the POST request will not be resolved automatically, the method can not be used getParameter HttpServletRequest class to obtain the POST request. Analyzing only the original requested content on the server side, the value of the parameter obtained therein.

XDomainRequest request issued by the object does not contain any information related to the user authentication, and the like include a cookie. This means that if the server requires authentication, the user authentication information needs to be transmitted through other HTTP requests, such as the session ID or the like.

Due to these limitations XDomainRequest objects, server-side is also necessary to make corresponding changes. These alterations include Back Access-Control-Allow-Origin header; for parsing "text / plain" type parameters sent by the browser; process request includes information related to user authentication.

Polyfill library examples in this article use is on GitHub Yaffle developed EventSource project . After using this polyfill library, and implement server-side modifications, you can use server push event in IE 8 and above browser. If you need to support IE 7, only using a simple polling or the Comet technology. Sample code resources see reference herein .

Conclusion

If you need to push data from the server to the browser-based HTML 5 specification standard techniques can be used include WebSocket server push and events. Developers can choose the right technology according to the specific needs of the application. If you just need to push data from the server, the server push event specification is simpler and easier to implement. In this paper the normative content of server push event, and implementation of server-side browser have carried out a detailed description of how to support IE browser also carried out a detailed analysis.

Guess you like

Origin www.cnblogs.com/leftJS/p/11041410.html