server-push servlet
Resin's server-push (Comet) servlet API enables streaming communication such as reverse AJAX dynamic updates for browser/JavaScript applications. The API encapsulates of the threading and communications issues between the request threads and the rest of the application. Resin's server-push (Comet) API lets server application push new data to the client as it becomes available. Administration and monitoring applications need to continually update the client when new information becomes available to the server. The architecture in the picture uses two HTTP streams to the server application, one for normal client-server requests, and a second unidirectional stream to send updates from the server to the client. In this example, we're using a browser with JavaScript, but the same architecture applies to a more sophisticated Flash monitoring application sending Hessian packets to update the monitoring display.
The example updates a comet.html page every two seconds with new data. In this case, just an updated counter. The components of the Comet/AJAX application look like:
The comet HTTP stream is a sequence of <script> tags containing JavaScript commands to update the browser's display. Because the browser executes the script as part of its progressive rendering, the user will see the updates immediately without waiting for the entire HTTP request to complete. In our example, the packet is a JavaScript
<script type="text/javascript"> window.parent.comet_update(1); </script> <!-- 2 second delay --> <script type="text/javascript"> window.parent.comet_update(2); </script> <!-- 2 second delay --> <script type="text/javascript"> window.parent.comet_update(3); </script> More sophisticated comet applications will use a dynamic-typed protocol to update the client. Browser-based applications could use JSON to update the client and Flash-based applications might use Hessian. In all cases, the protocol must be kept simple and designed for the client's requirements. Design separate, simple protocols for Flash and JavaScript browsers, rather than trying to create some complicated general protocol. The JavaScript command stream updates a parent HTML file which defines
the JavaScript commands and launches the Comet servlet request with an
<iframe> tag. Our <html> <body> Server Data: <span id="content">server data will be shown here</span> <script type="text/javascript"> function comet_update(value) { document.getElementById('content').innerHTML = value; }; </script> <iframe src="comet" style="width:1px;height:1px;position:absolute;top:-1000px"></iframe> </body> </html> The AsyncContext is the Servlet 3.0 encapsulation
of control and communication from the application's service to the
Comet servlet. Applications may safely pass the In the example, the package javax.servlet; public interface AsyncContext; { public ServletRequest getRequest(); public ServletResponse getResponse(); public boolean hasOriginalRequestAndResponse(); public void complete(); public void dispatch(); public void dispatch(String path); public void dispatch(ServletContext context, String path); public void start(Runnable run); } The comet servlet has three major responsibilities:
Like other servlets, only the comet servlet
may use the Process the initial request: our servlet just calls
Register the Send streaming data:. The package example; import java.io.*; import javax.servlet.http.*; import javax.servlet.*; import javax.inject.Current; public class TestComet extends GenericCometServlet { @Current private TimerService _timerService; @Override public void service(ServletRequest request, ServletResponse response) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; AsyncContext async = request.getAsyncContext(); if (async != null) { resume(request, response, async); return; } res.setContentType("text/html"); async = request.startAsync(); TestState state = new TestState(async); _timerService.addCometState(state); } private void resume(ServletRequest request, ServletResponse response, AsyncContext async) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; PrintWriter out = res.getWriter(); String count = req.getAttribute("comet.count"); out.print("<script type='text/javascript'>"); out.print("comet_update(" + count + ");"); out.print("</script>"); } } The connection can close for a number of reasons. The service might call
The sequence of calls for the example looks like the following:
Comet Servlet State MachineThe sequence of comet servlet calls looks like the following state
machine. After the initial request, the servlet spends most of its
time suspended, waiting for the
|