Resin Documentationapp server |
comet/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 CometController is Resin's thread-safe encapsulation
of control and communication from the application's service to the
Comet servlet. Applications may safely pass the In the example, the package com.caucho.servlet.comet; public interface CometController { public void wake(); public Object getAttribute(String name); public void setAttribute(String name, Object value); public void removeAttribute(String name); public void close(); } 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 com.caucho.servlet.comet.GenericCometServlet; import com.caucho.servlet.comet.CometController; public class TestComet extends GenericCometServlet { @Override public boolean service(ServletRequest request, ServletResponse response, CometController controller) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; res.setContentType("text/html"); TestState state = new TestState(controller); _service.addCometState(state); return true; } @Override public boolean resume(ServletRequest request, ServletResponse response, CometController controller) 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>"); return true; } } The connection can close for a number of reasons. Either the
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
|