Rémy Maucherat <r...@apache.org> 於 2016年11月2日 週三 下午5:28寫道:
> 2016-11-02 5:19 GMT+01:00 Bruce Huang <mailbru...@gmail.com>: > > > Thanks for your suggestion. > > > > I have tested on 8.0.38 release, but it even can't close the comet > > properly. On 8.0.23, after OutputStream.close(), I have to do > event.close() > > to make the END event to be fired correctly. > > > > ServletOutputStream servletOutputStream = > > event.getHttpServletResponse().getOutputStream(); > > > > servletOutputStream.write(triggerMessage); > > servletOutputStream.flush(); > > servletOutputStream.close(); > > > > event.close(); // add for NIO2 > > > > Why is it "add for NIO2" ? When closing comet, you should use event.close() > (why do you think this API exists ?) *and* flushing+closing the streams is > often a problem. Although I understand the systematic stream close (and > flush, sometimes) comes from java.io, it is useless in Servlets and > sometimes harmful. When I used comet in NIO protocol, I only do flush and close the stream. The END event will be fired after the stream to be closed and I do event.close() there. In NIO2, however, close stream will not fire the END event, so I had realized that I must do event.close() after the trigger has sent. > > > > > I found that the event.close() won't work from v8.0.27~8.0.38 and I could > > make the comet to be connected start from v8.0.9 to v8.0.38, but > > event.setTimeout() are not working on both of them. > > > > Since our server is running on Windows platform, we have to switch to > NIO2 > > for this issue > > http://tomcat.10.x6.nabble.com/Tomcat-8-uses-high-CPU-td5049333.html > > > > What is the error(s) you get with the latest 8.0 build ? > > I have followed your suggestion, not to do flush and close stream, just do event.close() as below. HttpServletResponse response = event.getHttpServletResponse(); response.addHeader("Content-Length", Integer.toString( triggerMessage.length)); response.addHeader("Content-Language", "en-US"); ServletOutputStream servletOutputStream = response.getOutputStream(); servletOutputStream.write(triggerMessage); event.close(); Before v8.0.26, after event.close(), I will received END event. After v8.0.27 to v8.0.38(latest build), the END event will be fired about 20 seconds later after event.close() and the below exception will be thrown. 03-Nov-2016 11:39:40.961 SEVERE [http-nio2-8443-exec-5] org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process Error reading request, ignored java.lang.IllegalStateException: Reading not allowed due to timeout or cancellation at sun.nio.ch.AsynchronousSocketChannelImpl.read(AsynchronousSocketChannelImpl.java:249) at sun.nio.ch.AsynchronousSocketChannelImpl.read(AsynchronousSocketChannelImpl.java:297) at org.apache.tomcat.util.net.SecureNio2Channel.read(SecureNio2Channel.java:792) at org.apache.tomcat.util.net.Nio2Endpoint.awaitBytes(Nio2Endpoint.java:871) at org.apache.coyote.http11.Http11Nio2Protocol$Http11ConnectionHandler.release(Http11Nio2Protocol.java:180) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:722) at org.apache.tomcat.util.net.Nio2Endpoint$SocketProcessor.doRun(Nio2Endpoint.java:1073) at org.apache.tomcat.util.net.Nio2Endpoint$SocketProcessor.run(Nio2Endpoint.java:1032) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:745) If I do not send any trigger to Trigger servlet, the comet from client will be disconnected after 20 seconds, I will received END event and the same exception as above will be thrown. Thanks, Bruce > Since Comet is removed in 8.5 (deprecated in 8.0) and NIO2 was new in 8.0, > it's not a very good combo for support of the feature, but we can give it a > shot. > > Rémy >