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
>

Reply via email to