反向AJAXServlet - Comet/Reverse-AJAX Servlet
作者:anotherbug 日期:2007-10-11 12:58:34
| cometcomm.gif(5.5 K) | |
| cometstate.gif(6.4 K) | |
Resin's 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 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.
Files in this tutorial
| WEB-INF/resin-web.xml | resin-web.xml configuration |
| WEB-INF/classes/example/TestCometServlet.java | The Comet servlet. |
| WEB-INF/classes/example/TimerService.java | Application service for timer/comet events. |
| WEB-INF/classes/example/CometState.java | The application's Comet controller state. |
| comet.html | Main HTML page linking comet servlet. |
Example Overview
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:
- Protocol: JavaScript function calls with a trivial argument.
- Client:
- View: HTML updated by JavaScript AJAX
- Controller: call server with an <iframe>
- Server:
- Service: TimerService manages the comet connections and wakes them
with new data. - Servlet: TestCometServlet generates <script> protocol tags from
new data from the TimerService on eachresume. - State: CometState encapsulates both the item's state (the timer count),
and the CometController needed to wake the servlet and
pass updated data.
- Service: TimerService manages the comet connections and wakes them
Streaming Protocol: <script> tags
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
comet_update(data) call, which updates the text field with
new data. Here's an example of the packet stream:
<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.
Browser Client
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 comet_update function finds the
HTML tag with id="content" and updates its HTML content
with the new data from the server.
<html>
<body>
Server Data:
server data will be shown here
<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>
CometController
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 CometController
to different threads, wake the servlet with wake(), and send
data with setAttribute.
In the example, the TimerService passes the updated
count to the servlet by calling
setAttribute("caucho.count", count), and wakes the servlet
by calling wake(). When the servlet resumes, it will
retrieve the count using request.getAttribute("caucho.count").
Note, applications must only use the thread-safe
CometController in other threads. As with other servlets, the
ServletRequest, ServletResponse, writers and
output stream can only be used by the servlet thread itself, never by
any other threads.
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();
}
Comet Servlet
The comet servlet has three major responsibilities:
- Process the initial request (
service). - Register the
CometControllerwith the service (service). - Send streaming data as it becomes available (
resume).
Like other servlets, only the comet servlet
may use the ServletRequest, ServletResponse or any
output writer or stream. No other thread may use these servlet objects,
and the application must never store these objects in fields or objects
accessible by other threads. Even in a comet servlet, the servlet objects
are not thread-safe. Other services and threads must use
the CometController to communicate with the servlet.
Process the initial request: our servlet just calls
setContentType("text/html"), since it's a trivial example.
A real application would do necessary database lookups and possibly
send more complicated data to the client.
Register the CometController:
our servlet registers the controller with the timer service by calling
addCometState. In general, the application state object will
contain the CometController as part of the registration
process.
Send streaming data:. The TimerService will set new
data in the "comet.count" attribute and wake()
the controller. When the servlet executes the resume() method,
it will retrieve the data, and send the next packet to the client.
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
service() or resume() methods may return false,
telling Resin to close the connection. The service might call
CometController.close() which will also close the connection.
Finally, the client may close the connection itself.
The sequence of calls for the example looks like the following:
servlet.service()is called for the initial request_service.addCometState()registers with theTimerService- after the
service()completes, Resin suspends the servlet. - The
TimerServicedetects an event, in this case the timer event. - The
TimerServicecallscontroller.setAttribute()to send new data. - The
TimerServicecallscontroller.wake()to wake the servlet. servlet.resume()processes the data and sends the next packet.- After the
resume()completes, Resin suspends the servlet again and we repeat as after step #3. - After the 10th data, the
TimerServicecallscontroller.close(), closing the servlet connection.
Comet Servlet State Machine
The 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 TimerService to call
wake().

- 共有 5 条评论
- 共有 5 条评论
订阅
上一篇
|

文章来自:
标签: 





Cheap Warhammer gold
Warhammer Online gold
WAR Gold
Buy Warhammer Gold
Warhammer Online Gold
Warhammer Gold for sale
Warhammer Accounts
Buy Warhammer Accounts
Cheap Warhammer Accounts
Warhammer Power leveling
WAR Power leveling
Warhammer Online Power Leveling
Warhammer CD Key
WAR CD Key
Warhammer Online CD Key
Warhammer Game Time Card
不知道你是否运行这个例子了吗?如果你解决了这个问题,能否发邮件给我:tower@188.com
脚本的效率有限,问题有什么解决方案吗?