On Sat, Oct 5, 2013 at 2:18 AM, Konstantin Preißer <kpreis...@apache.org>wrote:
> Hi Mark, > > > -----Original Message----- > > From: Mark Thomas [mailto:ma...@apache.org] > > Sent: Friday, October 4, 2013 11:58 PM > > To: Tomcat Developers List > > Subject: Re: 8.0.x / 7.0.x progress > > > > On 04/10/2013 22:49, Konstantin Preißer wrote: > > > Hi Mark, > > > > > > while I was developing and experimenting with a WebSocket application > > (that I think could be added to Tomcat 8's WebSocket examples), I think I > > found some more possible issues with the Websocket handling. One of > > these can be seen with the Snake example. > > > > > > > > > A) For NIO and APR connector: > > > It seems that when a client establishes a Websocket connection and then > > stops to read data from it (but doesn't close the connection, so that > writing > > data to the underlying TCP connection will be blocked), and then after > some > > time continues to read data from the Websocket connection, then Tomcat > > seems not to be able to read data from that client any more (and doesn't > > notice when the connection has been closed), but it can still read from > it. > > > > I think you have written read when you meant write somewhere in the > > previous sentence. > > Sorry, yes. I'll try again: > > It seems that when a client establishes a Websocket connection and then > stops to read data from it (but doesn't close the connection, so that at > Tomcat's side writing data to the underlying TCP connection will be > blocked), and then after some time the client continues to read data from > the Websocket connection, then Tomcat seems not to be able to read data > from that client any more (and doesn't notice when the connection has been > closed), but it can still write data to the client. > > > > > To reproduce: > > > 1) Start Tomcat (current trunk) on Windows 64-bit with Java7 64-bit and > > either NIO or APR connector. > > > 2) Open two instances of Firefox (that may or may not be on the same > > machine) and open the snake example. On both instances, press up or down > > key so that both snakes begin moving. > > > 3) Suspend one of the two Firefox processes (say Firefox B). This can > be > > done with "Process Explorer" [1] tool by right-clicking on the > firefox.exe > > entry and select "Suspend". You can see that Firefox B does not respond > any > > more, but on Firefox A the snakes continue to move. > > > 4) After some time, you can see that on Firefox A the snakes suddenly > stop > > moving. This is correct because the current code uses > RemoteEndpoint.Basic > > that may block on write() methods. > > > 5) Now resume Firefox B with Process Explorer. You can see that on both > > Firefoxes the snakes will continue to move. This means that both > Firefoxes > > are able to receive data from the Websocket connection. > > > 6) When you try to change the direction of the snake in Firefox A, > > everything works. However on Firefox B, the snake will not change its > > direction. This means that while Tomcat continues to send data to this > > Websocket connection, it cannot receive from it any more. > > > 7) If you close Firefox B, then the corresponding snake will not > disappear > > (so it seems Tomcat doesn't notice that the connection closed). > > > > It would be worth taking a look with something like Wireshark to see if > > the data is being sent to Tomcat. > > I have installed Wireshark now and can confirm that Firefox (after it is > resumed) still sends data over the TCP connection which Tomcat seems not to > be able to read. > Are there ACKs for the TCP packets? I'll try to reproduce the case. > > > > > B) For BIO connector: > > > I noticed that on Tomcat with BIO connector, when using a > > RemoteEndpoint.Async to asynchronously send data over the WebSocket > > connection, sendText(String, SendHandler) (or similar methods) will > block if > > the Remote endpoint does not read data from the connection, whereas for > > NIO and APR connector this method will always return immediately. > > > Is it intended that for the BIO connector those methods are blocking? > As > > the javadoc says, "Initiates the asynchronous transmission of a text > message. > > This method returns before the message is transmitted.", I would have > > expected that e.g. another Thread is used to write in blocking mode, so > that > > the sendText() method can return immediately. > > > > You can't do non-blocking IO with the BIO connector. All communication > > with BIO is blocking. This is working as designed. > > OK, but my understanding was that there is a difference between the terms > "synchronous/asynchronous" and "blocking/non-blocking" (but maybe the > meaning differs from programming language to programming language). > An excellent and detailed explanation on this topic can be found in "UNIX Network Programing" R. Stevens Vol 1 3td ed. p154-p160 > > For example, in .Net applications (C#) you can do Stream operations (read, > write) in a synchronous and asynchronous mode, regardless of whether the > underlying I/O supports NIO or only BIO. For asynchronous operations, you > can specify a callback that is called (from another thread) when the > operation has finished. > > When the underlying I/O supports NIO, an async operation will use NIO so > that an additional thread is not required (only when the operation has > completed, it will take an additional thread for the callback) . > However, when the underlying I/O doesn't support NIO, then you can still > do an asynchronous operation. E.g. if you do an async write(), then this > seems to be done by using an additional thread (from a thread pool) that > will use a blocking write(), and after that method returns, it calls your > callback to inform you that the write operation has completed. > > (Of course, this has at least the same costs (Thread usage) as using > synchronous writes if the I/O does not support NIO, but it will be > transparent to the application if the underlying I/O uses BIO or NIO.) > > This is why I was excepting that RemoteEndpoint.Async#sendText(...) > returns immediately, regardless of whether BIO or NIO is used. > > > Regards, > Konstantin Preißer > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org > For additional commands, e-mail: dev-h...@tomcat.apache.org > >