Preface
Today, users expect fast and dynamic applications that can be accessed through the web. This article series shows how to use reverse Ajax (reverse Ajax) technology to develop event-driven Web applications. Part 1 of the series describes reverse Ajax, polling, streaming, Comet, and long polling ). You have learned how comet uses HTTP long polling. This is the best way to reliably implement reverse Ajax, because all existing browsers provide support. Part 1 of the series illustrates how to use websocket to implement reverse Ajax. Some code examples are used to help describe websocket, flashsocket, server constraints, and request scope (request-scoped) service and long-lived suspension requests.
In this article, we will go deep into the details and discuss how to use Comet and websocket of different Web containers and APIs (servlet 3.0 and jetty continuations) in Web applications. i/O abstract libraries to transparently use Comet and websocket. Socket. Io uses function detection to determine whether the connection is established using websocket, Ajax long polling, Flash, or other methods.
Prerequisites
Ideally, If You Want To fully understand this article, you should have a certain understanding of javascrpit and Java. The example created in this article is built using Google guice, a dependency injection framework written in Java. To read the content mentioned in this article, you should be familiar with the concept of dependency injection frameworks such as guice, spring, and Pico.
To run the example in this article, you also need the latest version of Maven and JDK (see references ).
Server solutions for Comet and websocket
As you have learned in part 1, comet (long polling or stream) requires the server to suspend a request and resume or complete the request after a possible long delay. Part 1 describes how the server uses non-blocking I/O functions to process a large number of connections, and how they can only use threads to serve requests (each request has one thread mode ). You have also learned that the use of websocket depends on the server, and not all servers support websocket.
This section describes how to use Comet and websocket on Web servers such as jetty, tomcat, and grizzly if applicable. The source code provided in this article contains a chat web application example of jetty and tomcat. This section also discusses the following application servers: JBoss, glassfish, and APIs supported by websphere.
Jetty
Jetty is a web server that supports Java Servlet 3.0 specifications, websocket and many other integration specifications. Jetty:
1. Powerful and flexible Functions
2. Easy to embed
3. Support for VM, session cluster, and many functions that can be easily configured through Java code or XML for hosting services of Google App Engine.
The core jetty project is managed by the eclipse Foundation.
Since version 6, Jetty has added an asynchronous API called jetty continuation (jetty continuation), which allows the request to be paused and restored later. Table 1 provides a reference relationship between the supported specifications and APIs of the main jetty version series.
Table 1. jetty versions and support
Supports |
Jetty 6 |
Jetty 7 |
Jetty 8 |
Non-blocking I/O |
X |
X |
X |
Servlet 2.5 |
X |
X |
X |
Servlet 3.0 |
|
X |
X |
Jetty continuations (COMET) |
X |
X |
X |
Websockets |
|
X |
X |
To implement reverse Ajax using Comet, you can use jetty's continuation API, as shown in Listing 1:
Listing 1. jetty continuation API for Comet
// Pause a servlet method (get, post ......) Request:
Protected void doget (httpservletrequest req, httpservletresponse resp)
Throws servletexception, ioexception {
Continuation continuation = continuationsupport. getcontinuation (req );
// Optional. set timeout to prevent the request from being suspended for too long.
Continuation. setTimeout (0 );
// Suspend the request
Continuation. Suspend ();
// Save the reference for future use by another thread
Continuations. Offer (continuation );
}
// Then, from another thread that wants to send events to the customer:
While (! Continuations. isempty ()){
Continuation continuation = continuations. Poll ();
Httpservletresponse response =
(Httpservletresponse) Continuation. getservletresponse ();
// Write data to the response
Continuation. Complete ();
}
The complete Web application is included in the source code in this article. Jetty continuation is packaged in a jar archive file. You need to put this jar file in the WEB-INF/lib directory of the Web application to use the jetty comet function. Jetty continuation is available on Jetty 6, 7, and 8.
From jetty 7, you can also access the websocket function, put jetty's websocket JAR file under the web application's WEB-INF/lib directory to get access to jetty's websocket API, as shown in List 2:
Listing 2. jetty's websocket API
// Implement dowebsocketconnect and return the websocket implementation
Publicfinalclass reverseajaxservlet extends websocketservlet {
@ Override
Protected websocket dowebsocketconnect (httpservletrequest request,
String protocol ){
Return [...]
}
}
// Websocket example implementation
Class endpoint implements websocket {
Outbound outbound;
Publicvoid onconnect (outbound ){
This. Outbound = outbound;
}
Publicvoid onmessage (byte opcode, string data ){
Outbound. sendmessage ("Echo:" + data );
If ("close". Equals (data ))
Outbound. Disconnect ();
}
Publicvoid onfragment (Boolean more, byte opcode,
Byte [] data, int offset, int length ){
}
Publicvoid onmessage (byte opcode, byte [] data,
Int offset, int length ){
Onmessage (opcode, new string (data, offset, length ));
}
Publicvoid ondisconnect (){
Outbound = NULL;
}
}
There is a chat application example under the jetty-websocket directory of the downloaded source code. This example shows how to use jetty's websocket API.
Tomcat
Tomcat may be the most widely known Web server. It has been used for many years and has been integrated into early versions of JBoss application servers as Web containers. Tomcat is also used as a reference implementation for servlet specifications, but it is no longer used after servlet API 2.5, at this time, people began to look for another method based on non-blocking I/O (such as jetty ). Table 2 compares the supported specifications with the APIs of the two latest Tomcat versions.
Table 2. Tomcat support
Supports |
Tomcat 6 |
Tomcat 7 |
Non-blocking I/O |
X |
X |
Servlet 2.5 |
X |
X |
Servlet 3.0 |
|
X |
Advanced I/O (COMET) |
X |
X |
Websockets |
|
|
As shown in table 2, Tomcat does not support websocket; it has an API equivalent to jetty's continuation, which is called Advanced I/O's API that supports comet. Not so much as advanced I/O is a good place to use the comet API, it is better to say it is a low-layer surface package that encapsulates NiO. It lacks documentation and has almost no examples of using APIs. Listing 3 provides a servlet example that suspends and resumes requests in the chat web application. You can find the complete Web application in the source code of this article.
Listing 3. Tomcat APIs for Comet
Publicfinalclass chatservlet extends httpservlet
Implements cometprocessor {
Privatefinal blockingqueue events =
New linkedblockingqueue ();
Publicvoid event (cometevent EVT)
Throws ioexception, servletexception {
Httpservletrequest request = EVT. gethttpservletrequest ();
String user =
(String) request. getsession (). getattribute ("user ");
Switch (EVT. geteventtype ()){
Case begin :{
If ("get". Equals (request. getmethod ())){
EVT. setTimeout (integer. max_value );
Events. Offer (EVT );
} Else {
String message = request. getparameter ("message ");
If ("/disconnect". Equals (Message )){
Broadcast (User + "disconnected ");
Request. getsession (). removeattribute ("user ");
Events. Remove (EVT );
} Elseif (message! = NULL ){
Broadcast ("[" + User + "]" + message );
}
EVT. Close ();
}
}
}
}
Void broadcast (string message) throws ioexception {
Queue q = new queue list ();
Events. drainto (Q );
While (! Q. isempty ()){
Cometevent event = Q. Poll ();
Httpservletresponse resp = event. gethttpservletresponse ();
Resp. setstatus (httpservletresponse. SC _ OK );
Resp. setcontenttype ("text/html ");
Resp. getwriter (). Write (Message );
Event. Close ();
}
}
}
In tomcat, the asynchronous servlet must implement cometprocessor. For Asynchronous Servlets, Tomcat does not call standard HTTP methods (such as doget and dopost). Instead, events are sent to the event (cometevent) method. When a request arrives for the first time, check whether it is a get. If yes, it is suspended and EVT. Close () is not called. If it is a post, it means that the user sends a message, so it broadcasts the message to other cometevent, and then calls EVT. Close () to complete the POST request. At this end of the customer, the broadcast will send messages to all long polling requests, and the other long polling request will be immediately sent to receive the next event.
Grizzly and glassfish
Grizzly is not a Web container. It is more like a NiO framework that helps developers build scalable applications. It was developed as part of the glassfish project, but can also be used independently or embedded. Grizzly provides components to act as an HTTP/https server. Besides some other components, Grizzly also provides Bayeux protocol, Servlet, httpservice osgi, and comet components. Grizzly supports websocket, which is used in glassfish to provide comet and websocket support.
The Oracle Application Server glassfish is a reference implementation of the J2EE 6 specification. Glassfish is a complete suite similar to WebSphere and JBoss. It uses grizzly to support NiO, websocket, and comet. Its osgi-based modular architecture gives it real flexibility in component replacement. Table 3 illustrates glassfish's support for Comet and websocket.
Table 3. glashfish support
Supports |
Glassfish 2 |
Glassfish 3 |
Non-blocking I/O |
X |
X |
Servlet 2.5 |
X |
X |
Servlet 3.0 |
|
X |
Comet |
X |
X |
Websockets |
|
X |
Grizzly's usage is worth mentioning because it was originally intended to be used in an embedded way or directly through Java code. It is widely used as a framework supporting comet and websocket and can be embedded into a larger application. For example, glassfish provides Web deployment functions and Servlet standard APIs.
See the references section to get links to the websocket and comet examples in grizzly or glassfish. Because glassfish uses grizzly, the example should be able to run on both. Websocket APIs are very similar to jetty APIs, But comet APIs are more complex.
JBoss
JBoss is an Application server built on Tomcat. It supports comet and NiO from version 5. JBoss 7 is still under development, but it is also compared in table 4 below.
Table 4. JBoss support
Supports |
JBoss 5 |
JBoss 6 |
JBoss 7 |
Non-blocking I/O |
X |
X |
X |
Servlet 2.5 |
X |
X |
X |
Servlet 3.0 |
|
X |
X |
Comet |
X |
X |
X |
Websockets |
|
|
|
WebSphere
WebSphere is an IBM Application Server. WebSphere of version 8 supports servlet 3 APIs (including Standard Asynchronous APIs for Comet) (see references to learn about publishing announcements ).
Table 5. WebSphere support
Supports |
WebSphere 8 |
Non-blocking I/O |
X |
Servlet 2.5 |
X |
Servlet 3.0 |
X |
Comet |
X |
Websockets |
|
General Apis
Each server has its own local comet and websocket APIs. As you may have guessed, it may be difficult to write a portable web application. Servlet 3.0 contains additional methods for pending and resuming requests, allowing all web containers that support servlet 3.0 specifications to support comet and long polling requests.
Jetty provides a library called jetty continuation, which exists independently of the jetty container. The jetty continuation library is very intelligent and can detect available containers or specifications. If the application runs on the jetty server, the application uses the local jetty API. If the application runs on a container that supports servlet 3.0 specifications, the application uses this generic API; otherwise, a non-scalability implementation is required.
There is no standard for websocket in Java. Therefore, if you want to use websocket, you need to use the container vendor's API in Web applications.
Table 6 summarizes the technologies supported by various servers.
Table 6. technologies supported by servers
Container |
Comet |
Websocket |
Jetty 6 |
Jetty continuations |
N/ |
Jetty 7 |
Servlet 3.0 Jetty continuations |
Native jetty API |
Jetty 8 |
Servlet 3.0 Jetty continuations |
Native jetty API |
Tomcat 6 |
Advanced I/O |
N/ |
Tomcat 7 |
Servlet 3.0 Advanced I/O Jetty continuations |
N/ |
Glassfish 2 |
Native grizzly API |
N/ |
Glassfish 3 |
Servlet 3.0 Native grizzly API Jetty continuations |
Native grizzly API |
JBoss 5 |
Native JBoss API |
N/ |
JBoss 6 |
Servlet 3.0 Native JBoss API Jetty continuations |
N/ |
JBoss 7 |
Servlet 3.0 Native JBoss API Jetty continuations |
N/ |
WebSphere 8 |
Servlet 3.0 Jetty continuations |
N/ |
In addition to using container APIs, there is clearly no solution for websocket. For comet, each container that supports the servlet 3.0 specification supports comet. Jetty continuation has the advantage of providing support for Comet in all these containers. Therefore, some reverse Ajax libraries (This will be discussed in the next article in this series) Use jetty continuation as their server-side APIs.
Jetty continuation API is described in the jetty example in this article. The servlet 3.0 specification has been used and introduced in two comet examples in part 1 of this series.
Abstract Library
Consider all the major APIs (servlet 3.0 and jetty continuation), along with all the Localization support on the server side, and two main reverse Ajax implementation methods (COMET and websocket) on the client side ), it is not easy to bind JavaScript and Java code by writing your own code. You also need to consider timeout, connection failure, confirmation, sorting, buffering, and so on.
The rest of this article describes socket. i/O usage. Part 1 of this series will discuss atmosphere and cometd. These three libraries are open source and support comet and websocket on many servers.
Socket. Io
Socket. Io is a javascript client library similar to websocket. It provides a single API to connect to a remote server and send and receive messages asynchronously. By providing a common API, socket. Io supports the following types of transmission: websocket, flash socket, long polling, stream, permanent IFRAME, and jsonp polling. Socket. Io detects browser functions and then tries to select the best available transmission mode. Socket. the IO library is compatible with almost all browsers (including older ones, such as IE 5.5) and mobile browsers. It also has some other features, for example, heartbeat, timeout, disconnection, and error handling.
The socket. Io website (see references) describes the usage of the library, as well as the browser and reverse Ajax technologies used by the library. Basically, socket. Io uses a communication protocol, which enables the client library to communicate with the server endpoint, and the server endpoint to understand the socket. Io protocol. Socket. Io was initially developed for node. JS, A JavaScript engine used to build faster servers. Many projects provide support for other languages, including the Java language.
Listing 4 provides an example of using the socket. Io JavaScript library on the client. there are documents and examples on the socket. Io website.
Listing 4. Socket. Io client library usage
VaR socket = new IO. socket (document. domain ,{
Resource: 'chat'
});
Socket. On ('connect ', function (){
// Socket. Io is connected
});
Socket. On ('disconnect', function (disconnectreason, errormessage ){
// Socket. Io disconnected
});
Socket. On ('message', function (mtype, Data, error ){
// The server sends an event
});
// Now the Handler has been defined. You can establish a connection:
Socket. Connect ();
To use the socket. Io JavaScript library, you need the corresponding Java section called socket. Io Java (see references. This project was initially launched by the Apach wave team to provide reverse Ajax support for wave, before websocket was available. After socket. Io Java is derived, it is maintained by ovea (an event-driven Web Development Company), and then discarded. Due to multiple types of transmission, it is very complicated to develop backend support for socket. Io client library. Part 1 of this series shows that in order to achieve better scalability and browser support, it is not necessary to support multiple types of transmission in the client library, because long polling and websocket are enough. When websocket is unavailable, socket. Io is indeed a good choice.
Socket. Io Java uses the jetty continuation API to suspend and restore requests. It uses the local jetty websocket API as websocket support. You can determine on which server the web application using Socket. Io Java can run correctly.
The example in listing 5 illustrates how to use socket. Io on the server. You need to define a servlet that inherits socketioservlet and implement a method that returns an endpoint representation. This API is very similar to the websocket API. It is used on the server and is independent of the transmission method selected by the client. Socket. Io converts all transmission types to the same API on the server.
Listing 5. Use of socket. Io Java in the chat example-Servlet
Public final class chatservlet extends socketioservlet {
Private Final blockingqueue endpoints =
New linkedblockingqueue ();
@ Override
Protected socketioinbound dosocketioconnect
(Httpservletrequest request ){
String user =
(String) request. getsession (). getattribute ("user ");
Return user = NULL? Null: New Endpoint (this, user, request );
}
Void broadcast (string data ){
For (endpoint: endpoints ){
Endpoint. Send (data );
}
}
Void add (endpoint ){
Endpoints. Offer (endpoint );
}
Void remove (endpoint ){
Endpoints. Remove (endpoint );
}
}
Listing 6 describes how to return an endpoint.
Listing 6. Socket. Io Java library usage in the chat example-endpoint
Class endpoint implements socketioinbound {
[...]
Private socketiooutbound outbound;
[...]
@ Override
Publicvoid onconnect (socketiooutbound outbound ){
This. Outbound = outbound;
Servlet. Add (this );
Servlet. Broadcast (User + "connected ");
}
@ Override
Publicvoid ondisconnect (disconnectreason reason,
String errormessage ){
Outbound = NULL;
Request. getsession (). removeattribute ("user ");
Servlet. Remove (this );
Servlet. Broadcast (User + "disconnected ");
}
@ Override
Public void onmessage (INT messagetype, string message ){
If ("/disconnect". Equals (Message )){
Outbound. Close ();
} Else {
Servlet. Broadcast ("[" + User + "]" + message );
}
}
Void send (string data ){
Try {
If (outbound! = NULL
& Outbound. getconnectionstate () = connectionstate. Connected ){
Outbound. sendmessage (data );
}
} Catch (ioexception e ){
Outbound. Close ();
}
}
}
The complete example of socket. Io is stored in the socketio directory of the source code.
Conclusion
All Web containers support comet, and most containers support websocket. Even if the specifications bring about several different localization implementations, you can still use Comet and universal APIs (servlet 3.0 and jetty continuation) to develop Web applications. More optimistically, you can use libraries such as socket. Io to utilize the powerful functions of comet and websocket in a transparent manner. There are also two libraries, atmosphere and cometd, which will be discussed in the next article in this series. These three libraries provide multi-browser support and excellent user experience, as well as the benefits of error handling, simpler API, timeout and reconnection.
Download
Description name size Download Method
Source code reverse_ajaxpt3_source.zip 21kb HTTP