Post: http://www.developersky.net/thread-63-1-1.html
For a long time, the HTTP protocol strictly follows the request-response model. The client sends a request to the server. The server responds to the request and sends the response back to the client. That is to say, all interactions are initiated by the client, and the server does not initiate any interactions.
To create more interactive web applications, Ajax emerged, implementing a dynamic method for retrieving data from the server. By using Ajax, the browser sends an HTTP request through the XMLHttpRequest API. XMLHttpRequest allows us to send an asynchronous HTTP request to the server without blocking the user interface to obtain data. However, Ajax does not define a new HTTP request type, but only moves the HTTP request sending work to the background without affecting users' operations. Therefore, Ajax does not break the request-response model, or the browser pulls data from the server.
Another technology is comet, also known as reverse Ajax. Like Ajax, comet is built on an existing HTTP protocol. Comet maintains a long-lived HTTP connection and sends a 'false' request to obtain the response.
These are all solutions to break the HTTP protocol restrictions. But in HTML5, this restriction will be broken. The HTML5 specification contains many powerful features that can turn browsers into a fully functional Ria client platform. Server-sent event and websockets are two of the features. These two features can help us implement the server's function of pushing data to the client.
In this article, we will first introduce the server-sent events features
Server-sent events
Server-sent events actually standardizes the comet technology. Server-sent events specifications "define an API to open an HTTP connection through which notifications pushed from the server can be obtained ". Server-sent events contains the new HTML element eventsource and the new MIME type text/event-stream. This MIME type defines the event framework format.
<HTML> <br/> <pead> <br/> <MCE: Script Type = 'text/JavaScript '> <! -- <Br/> var source = new eventsource ('events'); <br/> source. onmessage = function (event) {<br/> EV = document. getelementbyid ('events'); <br/> eV. innerhtml + = "<br> [in]" + event. data; <br/>}; </P> <p> // --> </MCE: SCRIPT> <br/> </pead> <br/> <body> <br/> <Div id = "events"> </div> <br/> </body> <br/> </ptml>
Eventsource indicates the end point of the client that receives the event. The client creates an eventsource object to open an event stream. When an eventsource object is created, the object receives an event source URL as its constructor parameter. The onmessage event processor is called each time a new event data is received.
Generally, the browser limits the number of connections to each server. In some cases, loading multiple pages containing eventsource objects in the same domain will create a connection dedicated to this eventsource for each eventsource, in this case, the number of connections will soon exceed the limit. To handle this situation, we can use the shared webworker, which shares an eventsource instance. In addition, by defining the browser-specific eventsource implementation, we can achieve that if the URLs of the two eventsources are the same, they will reuse the same connection. In this case, the shared connection is managed by the browser-specific eventsource.
When the event stream is opened, the browser will send the following HTTP request.
Request:
GET/events HTTP/1.1 <br/> HOST: myserver: 8875 <br/> User-Agent: Mozilla/5.0 (windows; U; Windows NT 5.1; de-de) <br/> applewebkit/532 + (khtml, like gecko) version/4.0.4 <br/> Safari/531.21.10 <br/> Accept-encoding: gzip, deflate <br/> Referer: http: // myserver: 8875/<br/> Accept: text/event-stream <br/> last-event-ID: 6 <br/> Accept-language: de-de <br/> cache-control: No-Cache <br/> connection: keep-alive
Accept defines the required format of text/event-stream. Although the server-sent events Specification defines the MIME type of text/event-stream, this specification also allows other event framework formats. However, the server-sent events must support the test/event-stream format.
According to the text/event-stream format, an event consists of one or more comment rows and field rows. A comment row is a row starting with a colon. The field line consists of the field name and field value. The field name and field value are also separated by a colon. Multiple events are separated by empty lines. The following is an example of response:
Response:
HTTP/1.1 200 OK <br/> server: xlightweb/2.12-html5preview6 <br/> Content-Type: text/event-stream <br/> expires: Fri, 01 Jan 1990 00:00:00 GMT <br/> cache-control: No-cache, no-store, Max-age = 0, must-revalidate <br/> Pragma: no-Cache <br/> connection: Close </P> <p>: time stream <br/> retry: 5000 </P> <p> ID: 7 <br/> data: Thu Mar 11 07:31:30 CET 2010 </P> <p> ID: 8 <br/> data: thu Mar 11 07:31:35 CET 2010 </P> <p> [...]
According to the definition, event stream should not be cached. To avoid caching, the response header contains cache-control, and the response is disabled.
In the above example, the response contains three events. The first event contains a comment row and a retry field. The second event and the third event both contain an ID field and a data field. The data field contains the event data. In the preceding example, the current time is used. The ID field is used to track the processing process in event stream. In the preceding example, the server-side application writes an event to the event stream every five seconds. When eventsource receives the event, the onmessage event processor is called.
The difference is that the first event does not trigger the onmessage processor. The first event contains only one comment row and one retry field without data fields. The retry field is used for reconnection. The retry field defines the reconnection time in milliseconds. If such a field is received, eventsource updates its related reconnection time attributes. In the case of a network error, the reconnection time plays an important role in improving the reliability. When the eventsource instance finds that the connection is disconnected, the connection is automatically rebuilt after the specified reconnection time.
We can see that in HTTP request, we can specify the last-event-id. Eventsource specifies this value when recreating the connection. Each time eventsource receives an event containing the ID field, the last event ID attribute of eventsource is changed, the last event ID attribute of eventsource is written into the last-event-ID of the HTTP request. In this way, if the server implements lasteven TID processing, it can ensure that no received events will be sent in the re-built connection.
The following code is an example of an HTTP server based on the Java HTTP library xlightweb (including HTML5 preview extension.
Class serverhandler implements ihttprequesthandler {<br/> private final timer = new timer (false); <br/> Public void onrequest (ihttpexchange exchange) throws ioexception {<br/> string requesturi = exchange. getrequest (). getrequesturi (); <br/> If (requesturi. equals ("/serversenteventexample") {<br/> sendserversendpage (exchange, requesturi); <br/>} else if (requesturi. equals ("/events") {<br /> Sendeventstream (exchange); <br/>}else {<br/> exchange. senderror (404); <br/>}< br/> private void sendserversendpage (ihttpexchange exchange, <br/> string URI) throws ioexception {<br/> string page = "<HTML>/R/N" + <br/> "<pead>/R/N" + <br/> "< MCE: script Type = 'text/JavaScript '> <! -- <Br/>/R/N "+ <br/>" Var source = new eventsource ('events');/R/N "+ <br/>" source. onmessage = function (event) {/R/N "+ <br/>" Ev = document. getelementbyid ('events');/R/N "+ <br/>" Ev. innerhtml + =/"<br> [in]/" + event. data;/R/N "+ <br/>"};/R/N "+ <br/>" <br/> // --> </MCE: SCRIPT>/R/N "+ <br/>" </pead>/R/N "+ <br/>" <body>/R/N "+ <br/> "<Div id =/" events/"> </div>/R/N" + <br/> "</body>/R/N" + <br/> "</ptml>/R/N "; <br/> exchange. send (New httpresponse (200, "text/html", page); <br/>}< br/> private void sendeventstream (final ihttpexchange exchange) <br/> throws ioexception {<br/> // get the last Id string <br/> final string idstring = exchange. getrequest (). getheader (<br/> "last-event-ID", "0"); <br/> // sending the Response Header <br/> final bodydatasink sink = exchange. send (New <br/> httpresponseheader (200, "text/event-stream"); <br/> timertask TT = new timertask () {<br/> private int id = integer. parseint (idstring); <br/> Public void run () {<br/> try {<br/> event = new event (new date (). tostring (), ++ ID); <br/> sink. write (event. tostring (); <br/>}catch (ioexception IOE) {<br/> cancel (); <br/> sink. destroy (); <br/>}< br/>}; <br/> event = new event (); <br/> event. setretrymillis (5*1000); <br/> event. setcomment ("time stream"); <br/> sink. write (event. tostring (); <br/> timer. schedule (TT, 3000,300 0); <br/>}< br/> xhttpserver Server = new xhttpserver (8875, new serverhandler ()); <br/> server. start ();
The server-sent events specification recommends sending keep-alive comments regularly if no other data is to be sent. In this way, the proxy server can close the connection when an HTTP connection is inactive for a period of time, so that the proxy server can close idle connections to avoid wasting the connection on the HTTP server with no response. The annotation event is sent so that this mechanism does not occur in a valid connection. Although eventsource automatically reconstructs the connection, sending the annotation event can avoid unnecessary reconnection.
Server-sent event is based on HTTP streaming. As mentioned above, response will always open. when an event occurs on the server side, the event will be written to response. Theoretically, if the network intermediary such as the HTTP proxy does not immediately forward part of the response, HTTP streaming may cause some problems. Currently, the http rfc (rfc2616 Hypertext Transfer Protocal-HTTP/1.1) does not require partial response to be forwarded immediately. However, many popular and well-working web applications are based on HTTP streaming. In addition, product-level intermediaries usually avoid buffering a large amount of data to reduce memory usage.
Unlike other popular coment protocols such as Bayeux and bosh, server-sent event only supports one-way channel from server to client. The Bayeux protocol supports two-way communication channels. In addition, Bayeux can use HTTP streaming and polling. The Bosh Protocol also supports two-way communication channels, but Bosh is based on the polling mechanism. (The so-called polling means that the client regularly sends a request to the server to obtain data ).
Although server-sent events has fewer functions than Bayeux and bosh, when only one-way servers need to push data to the client (in many cases ), server-sent events has the potential to become the dominant protocol. The server-sent events protocol is much simpler than bayeus and bosh. In addition, server-sent events is supported by all HTML5-compatible browsers (this is the power of specifications ).
Post: http://www.developersky.net/thread-63-1-1.html