我正在尝试创建一个非常简单的Comet Servlet,它将向订阅者推送"Hello World"消息。
然后我的 Runnable 看起来像这样:
现在我的Dojo CometD代码看起来像这样:
我做错了什么? 为什么cometD订阅会调用
附注:我按照Tomcat配置切换到了Nio。
@WebServlet("/ChatServlet")
public class ChatServlet extends HttpServlet implements CometProcessor {
private static final long serialVersionUID = 1L;
private MessageSender messageSender = null;
private static final Integer TIMEOUT = 60 * 1000;
public void init(ServletConfig config) throws ServletException {
messageSender = new MessageSender();
Thread messageSenderThread =
new Thread(messageSender);
messageSenderThread.setDaemon(true);
messageSenderThread.start();
}
public void destroy() {
// messageSender.stop();
messageSender = null;
}
@Override
public void event(CometEvent event) throws IOException, ServletException {
HttpServletRequest request = event.getHttpServletRequest();
HttpServletResponse response = event.getHttpServletResponse();
if (event.getEventType() == CometEvent.EventType.BEGIN) {
request.setAttribute("org.apache.tomcat.comet.timeout", TIMEOUT);
System.out.println("Begin for session: " + request.getSession(true).getId());
messageSender.setConnection(response);
}
else if (event.getEventType() == CometEvent.EventType.ERROR) {
System.out.println("Error for session: " + request.getSession(true).getId());
event.close();
} else if (event.getEventType() == CometEvent.EventType.END) {
System.out.println("End for session: " + request.getSession(true).getId());
event.close();
} else if (event.getEventType() == CometEvent.EventType.READ) {
throw new UnsupportedOperationException("This servlet does not accept data");
}
}
}
然后我的 Runnable 看起来像这样:
public class MessageSender implements Runnable {
protected boolean running = true;
protected final List<String> messages = new ArrayList<String>();
private ServletResponse connection;
public synchronized void setConnection(ServletResponse connection){
this.connection = connection;
notify();
}
@Override
public void run() {
while (running) {
if (messages.size() == 0) {
try {
synchronized (messages) {
messages.wait();
}
} catch (InterruptedException e) {
// Ignore
}
}
String[] pendingMessages = null;
synchronized (messages) {
pendingMessages = messages.toArray(new String[0]);
messages.clear();
}
try {
if (connection == null){
try{
synchronized(this){
wait();
}
} catch (InterruptedException e){
// Ignore
}
}
PrintWriter writer = connection.getWriter();
writer.println("hello World");
System.out.println("Writing Hello World");
writer.flush();
writer.close();
connection = null;
System.out.println("Closing connection");
} catch (IOException e) {
System.out.println("IOExeption sending message"+e.getMessage());
}
}
}
}
现在我的Dojo CometD代码看起来像这样:
<script src="dojo/dojo.js"></script>
<script type="text/javascript">
dojo.require("dojox.cometd");
dojo.addOnLoad(function(){
dojox.cometd.init("ChatServlet");
dojox.cometd.subscribe("ChatServlet", window, "alertMessage");
});
function alertMessage(message) {
alert("Message: " + message);
}
</script>
现在当我加载客户端时,我遇到了以下错误:
Begin for session: C898A372F1B1199C04CA308F715ABC36Nov 6, 2011 2:00:48 PM org.apache.catalina.core.StandardWrapperValve event
SEVERE: Servlet.service() for servlet [com.vanilla.servlet.ChatServlet] in context with path [/Servlet3Comet] threw exception
java.lang.UnsupportedOperationException: This servlet does not accept data
at com.vanilla.servlet.ChatServlet.event(ChatServlet.java:75)
Error for session: C898A372F1B1199C04CA308F715ABC36
End for session: C898A372F1B1199C04CA308F715ABC36
我做错了什么? 为什么cometD订阅会调用
CometEvent.EventType.READ
?
有人有可行的comet示例吗?附注:我按照Tomcat配置切换到了Nio。
BEGIN -> READ -> READ -> READ -> ERROR/TIMEOUT
,在这里阅读 http://tomcat.apache.org/tomcat-6.0-doc/aio.html。所以你有一个开始,如果有数据,就会调用READ。尝试实现EventType.READ并查看发生了什么,从这里获取一些灵感 http://svn.apache.org/viewvc/tomcat/trunk/webapps/examples/WEB-INF/classes/chat/ChatServlet.java?revision=1380715&view=markup。 - Jasonw