Traditionally, a web system works in such a way that the client makes a request and the server responds. This approach does not meet the needs of many real-world applications, such as:
Monitoring system: background hardware hot swap, LED, temperature, voltage changes; Instant messaging system: other users log in and send messages; Instantaneous** system: the content of the background database changes; These applications require the server to be able to deliver updated information to the client in real time, without the client having to make a request. There are some solutions for the "server push" technology in practical applications, and these solutions are divided into two categories in this paper: one type needs to install plug-ins on the browser side, transmit information based on socket interfaces, or use RMI and CORBA for remote calling; The other type does not require the browser to install any plug-ins, and is based on HTTP persistent connections.
When applying "server push" to a web application, the first thing to consider is how to receive and process information on the browser side with limited functionality
How the client receives and processes information, and whether it needs to use sockets or remote calls. Whether the client renders an HTML page or a J**A applet or flash window to the user. If you use sockets and remote calls, how to modify the display of HTML in combination with j**ascript. The format of the information communicated between the client and the server, and what kind of error handling mechanism is adopted. Whether the client needs to support different types of browsers such as IE and Firefox, and whether it needs to support both Windows and Linux platforms. If the user of the web application accepts that the application will only function if the flash user is installed, then using the flash xmlsocket is also a viable solution.
The basis for the implementation of such a scheme is:
Flash provides the XMLsocket class. Tight integration of j**ascript and flash: j**ascript can directly call the interface provided by the flash program. Here's how to do it: Embed a flash program that uses the XMLsocket class in the HTML page. j**ascript communicates with the server-side socket by calling the socket interface provided by this flash program. J**Ascript can easily control the display of the content of an HTML page after receiving the information delivered in XML format on the server side.
For more information on how to build a Flash program that acts as a bridge between J**Ascript and Flash XMLase, and how to call the interface provided by Flash in J**Ascript, we can refer to the Socket Demo and SocketJS provided by the Aflax (Asynchronous Flash and XML) project (see Reference Resources).
The close integration of j**ascript and flash greatly enhances the processing power of the client. From Flash v70.Starting with 19, the restriction that the port of xmlsocket must be greater than 1023 has been removed. The Linux platform also supports the Flash XMLsocket scheme. But the disadvantages of this scenario are:
The client must have a flash server installed; Because xmlsocket does not have an HTTP tunneling function, the xmlsocket class cannot automatically pass through the firewall; Because it is a socket interface, you need to set a communication port, and firewalls and servers may also restrict non-HTTP channel ports; However, this solution has been widely used in some online chat rooms and online interactive games.
Use the j**a applet on the client side, throughj**a.net.socket
orj**a.net.datagramsocket
orj**a.net.multicastsocket
Establish a socket connection with the server side, so as to achieve "server push".
The biggest disadvantage of this solution is that the j**a applet cannot update the content of the html page through j**ascript after receiving the information returned by the server.
As the foreground of a web application, the browser has limited processing capabilities. The development of browsers requires the client to upgrade the software, and at the same time, due to the diversity of the client browser software, in a sense, it also affects the promotion of new browser technologies. In a web application, the browser's main job is to send requests, parse the information returned by the server, and display it in different styles. AJAX is the result of an evolution in browser technology that improves the responsiveness of single-user operations by sending asynchronous requests on the browser side. But the web is inherently a multi-user system, and for any user, the server can be thought of as a different user. The development of existing AJAX technology does not solve the problem of delivering updated information to the client in real time in a multi-user web application, so that the user may be operating with "outdated" information. The use of AJAX makes it possible to update data in the background more frequently.
Figure 1A comparison of the traditional web application model with an AJAX-based model.
Server push is a technology that has existed for a long time, and it was mainly implemented through the client's socket interface or server-side remote call. Because the development of browser technology is relatively slow, it does not provide good support for the implementation of "server push", and it is difficult to have a perfect solution to implement server push and use it in commercial programs in pure browser applications.
In recent years, due to the popularity of AJAX technology and the fact that embedding iframes in the ActiveX component of "HTMLFILE" can solve the loading and display problem of IE, some popular applications such as Meebo, Gmail+Gtalk have used these new technologies in their implementations; At the same time, there are indeed many requirements for "server push" in real applications. For these reasons, browser-only "server push" technology is starting to gain traction, with Alex Russell (Dojo Toolkit's project lead) calling this HTTP persistent connection-based server push technology that doesn't require a plug-in to be installed on the browser side as Comet.
There are already some mature COMET applications and various open source frameworks; Some web servers, such as Jetty, are also making a lot of improvements to support long connections with a lot of concurrency. For the latest developments in COMET technology, please refer to the Comet wiki.
Here's a look at the implementation models for both Comet apps.
As shown in Figure 1A comparison of the traditional web application model with the AJAX-based model shows that the advent of AJAX allows J**Ascript to call the XMLhttpRequest object to make an HTTP request, and the J**Ascript response handler updates the display of the HTML page based on the information returned by the server. Using AJAX to implement "server push" differs from traditional AJAX applications in that the server side blocks requests until there is a data pass or timeout. The client-side j**ascript response handler re-establishes the connection by making another request after processing the information returned by the server. When the client processes the received data and re-establishes the connection, new data may arrive on the server side; This information will be stored on the server until the client re-establishes the connection, and the client will retrieve all the information from the current server at once. Figure 2Server push model based on long polling.
Some applications and examples such as "meebo" and "pushlet chat" use this method of long polling. This long polling method can also be called a "pull" as opposed to "polling". Because this scheme is based on AJAX, it has some advantages: requests are issued asynchronously; No plug-in installation required; IE and Mozilla Firefox all support AJAX.
In this long polling mode, the client calls the ** function when the readystate of xmlhttprequest is 4 (that is, the data transfer ends) to process the information. When readystate is 4, the data transfer ends and the connection is closed. Mozilla Firefox provides support for Streaming AJAX, i.e. when ReadyState is 3 (data is still in transit), the client can read the data and thus be able to read and process the information returned by the server without having to close the connection. When IE is ReadyState 3, the data returned by the server cannot be read, and currently IE does not support streaming AJAX-based.
Iframe is a type of HTML markup that has been around for a long time, and by embedding a hidden frame in an HTML page, and then setting the src attribute of this hidden frame to a request for a persistent connection, the server side is constantly feeding data to the client.
Figure 3Server push model based on stream mode.
The AJAX solution mentioned in the previous section is to process the data retrieved from the server by XMLhttpRequest in j**ascript, and then j**ascript can easily control the display of the html page. The same idea is applied to the client side of the iframe scheme, where the iframe server does not return data displayed directly on the page, but instead returns a call to the client's j**ascript function, such as ".”。The server side passes the returned data as an argument to the client's j**ascript function; The client browser's j**ascript engine executes it when it receives a j**ascript call from the server.
As you can see from Figure 3, the connection is not closed every time the data is transmitted, but only when there is a communication error or when the connection is rebuilt (some firewalls are often set to drop long connections, and the server can set a timeout to notify the client to re-establish the connection and close the original connection). There is an obvious downside to using an iframe to request a persistent connection: the progress bar at the bottom of IE and Morzilla Firefox will show that the load is not complete, and the icon above the IE will rotate to indicate that the load is in progress. Google's geniuses used an ActiveX called "HTMLFILE" to solve the loading display problem in IE and applied it to the Gmail+Gtalk product. Alex Russell in "What else is Burried down in the depth's of Google's amazing j**ascript?This method is described in the article. zeitoun **comet-iframe.tar.GZ, which encapsulates a j**ascript comet object based on iframe and htmlfile, supports IE and Mozilla Firefox browsers, and can be used as a reference. (See References).
The above describes two "server-push" architectures based on HTTP persistent connections, and describes more about the techniques for clients to handle persistent connections. For a practical application, the stability and performance of the system are very important. There are a lot of details to consider when using HTTP persistent connections for real-world applications.
We have this experience when we use IE files, and from the same web server file, there can only be a maximum of two files at the same time. The third file will be blocked until the previous file is finished. This is because of HTTP 11 The specification states that the client should not have more than two HTTP connections to the server, as new connections will be blocked. IE strictly adheres to this rule in its implementation.
http 1.1 The restriction on two persistent connections will bring the following phenomenon to web applications that use persistent connections: if the client opens more than two IE windows to access the same web server that uses persistent connections, the HTTP request of the third IE window is blocked by the persistent connection of the first two windows.
Therefore, when developing persistent applications, it is necessary to pay attention to the fact that in pages that use multiple frames, do not establish an HTTP persistent connection for each frame page, which will block other HTTP requests, and consider the design to let multiple frame updates share a single persistent connection.
A typical web server creates a thread for each connection, and if you use Comet in a large business application, the server side needs to maintain a large number of concurrent persistent connections. In this application context, load balancing and clustering technologies need to be considered on the server side; Or make some improvements to persistent connections on the server side.
The development of applications and technologies always brings new needs, which in turn drives the development of new technologies. http 1.1 vs. 10 The specification has one big difference:1Under the 0 specification, the server will close the socket connection after processing each get post request; And 11 The server maintains this connection and is idle for the time between two requests. j**a 1.4 Introduced j**a. with support for asynchronous IONIO Package. When a connection is idle, the thread resources allocated for the connection are returned to the thread pool and can be used by new connections. When a customer with an originally idle connection makes a new request, a thread resource is allocated from the thread pool to process the request. This technique is very effective in reducing the resource load on the server in scenarios where the probability of the connection being idle is high and the number of concurrent connections is high.
However, with the use of ajax making requests more frequent and comets taking up a connection for a long time, the server model described above becomes very inefficient in the context of new applications, and the limited number of threads in the thread pool may even block new connections. The Jetty 6 web server has a number of innovative improvements to the characteristics of Ajax and Comet applications, please refer to the article "Ajax, Comet and Jetty" (see Resources).
When using persistent connections, there is a very common scenario: the client web page needs to be closed, and the server is still in a state of reading data, and the client needs to notify the server to close the data connection in time. After receiving the shutdown request, the server first wakes up from the blocked state of reading data, releases the resources allocated to the client, and then closes the connection.
Therefore, by design, we need to make the client's control request and data request use different HTTP connections so that the control request will not be blocked.
In terms of implementation, if it is a persistent connection based on iframe streaming, the client page needs to use two iframes, one is a control frame, which is used to send a control request to the server, and the control request can receive a response quickly and will not be blocked; One is the display frame, which is used to send a persistent connection request to the server. In the case of long AJAX-based polling, the client can asynchronously issue an XMLhttpRequest request to notify the server to close the data connection.
Maintaining a persistent connection between the browser and the server introduces some uncertainty to the communication: because the data transfer is random, the client does not know when the server will have the data to be transmitted. The server side needs to ensure that when a client is no longer working, the resources allocated to the client are released to prevent memory leaks. There is therefore a need for a mechanism to let both sides know that everyone is functioning normally. On the implementation:
The server sets a time limit when blocking reads, and after the timeout, the blocked read call will be returned, and the heartbeat information that no new data has arrived will be sent to the client. In this case, if the client is closed, the server will write data to the channel abnormally, and the server will release the resources allocated to the client in time. If the client is using an AJAX-based long polling method; After the server returns data and closes the connection, if no further request from the client is received after a certain period of time, the client is considered to be unable to work properly and the resources allocated and maintained for the client are released. If an exception occurs in the processing of information by the server, you need to send an error message to notify the client, release resources, and close the connection. Pushlet is an open-source COMET framework that has a lot to learn from in terms of design, and is very valuable for developing lightweight COMET applications.
The observer model pushlet uses the observer model: the client sends a request and subscribes to an event of interest; The server assigns a session ID to each client as a token, and the event source multicasts the newly generated events to the subscriber's event queue.
The client-side j**ascript library pushlet provides an ajax-based j**ascript library file for "server push" in the long polling mode; An iframe-based j**ascript library file is also provided for "server push" in the streaming mode.
The j**ascript library does a lot of encapsulation:
Define the communication status of the client:state_error
state_abort
state_null
state_ready
state_joined
state_listening
;The session ID assigned by the server is saved, and the session ID is attached to each request after the connection is established. Yesjoin()
le**e()
subscribe()
unsubsribe()
listen()
and other APIs for page calls; Provides an interface to the j**ascript function for handling the responseondata()
onevent()
…Web pages can easily communicate with the server using the APIs encapsulated by these two j**ascript library files.
The client-server communication information format pushlet defines a set of information formats for client-server communication, using XML format. Defines the type of request that the client sends:join
le**e
subscribe
unsubscribe
listen
refresh
;and the type of event responded to:data
join_ack
listen_ack
refresh
heartbeat
error
abort
subscribe_ack
unsubscribe_ack
The server-side event queue management pushlet is implemented on the server side using J**A servlets, and its data structure design framework can still be applied to back-end clients written in PHP and C.
Pushlet allows clients to choose to use streams, pull (long polling), and polling methods. The server-side processes the fetchevents differently when reading the event queue (fetchevents) depending on the way the customer chooses. Polling modefetchevents()
Will be back soon. If it times out, it will send a "heartbeat" event to the client with no new information received, and if it is in the "pull" mode, it will pass the "heartbeat" and "refresh" event to the client to notify the client to re-issue the request and establish a connection.
The session management between the client server is sent on the client sidejoin
When requesting, the client is assigned a session ID and passed to the client, which is then used by the client to identify the clientsubscribe
withlisten
Request. The server side maintains a subscribed topic collection, event queue, for each session.
The server-side event source multicasts new events to the event queue for each session (i.e., subscriber).
This article describes how to choose the appropriate solution to develop a "server-push" application on the basis of existing technologies, and the optimal solution depends on the application requirements. Compared with traditional web applications, developing Comet applications is still challenging.
In order to make the Comet model suitable for large-scale commercial applications and facilitate users to build Comet applications, in recent years, many new technologies have emerged in both servers and browsers, as well as many open-source Comet frameworks and protocols. Demand is driving the development of technology, and it is believed that the adoption of Comet will become as ubiquitous as Ajax.