Return-Path: X-Original-To: apmail-tomcat-dev-archive@www.apache.org Delivered-To: apmail-tomcat-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 382E3F4E1 for ; Fri, 4 Oct 2013 23:18:41 +0000 (UTC) Received: (qmail 68414 invoked by uid 500); 4 Oct 2013 23:18:40 -0000 Delivered-To: apmail-tomcat-dev-archive@tomcat.apache.org Received: (qmail 68337 invoked by uid 500); 4 Oct 2013 23:18:39 -0000 Mailing-List: contact dev-help@tomcat.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "Tomcat Developers List" Delivered-To: mailing list dev@tomcat.apache.org Received: (qmail 68328 invoked by uid 99); 4 Oct 2013 23:18:39 -0000 Received: from minotaur.apache.org (HELO minotaur.apache.org) (140.211.11.9) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 04 Oct 2013 23:18:39 +0000 Received: from localhost (HELO NamePC) (127.0.0.1) (smtp-auth username kpreisser, mechanism login) by minotaur.apache.org (qpsmtpd/0.29) with ESMTP; Fri, 04 Oct 2013 23:18:39 +0000 From: =?UTF-8?Q?Konstantin_Prei=C3=9Fer?= To: "'Tomcat Developers List'" References: <524B16DC.50506@apache.org> <524C57AA.4020501@apache.org> <524DC7E8.104@apache.org> <000c01cec14b$9e22ecc0$da68c640$@apache.org> <524F39FE.10504@apache.org> In-Reply-To: <524F39FE.10504@apache.org> Subject: RE: 8.0.x / 7.0.x progress Date: Sat, 5 Oct 2013 01:18:25 +0200 Message-ID: <000d01cec158$08757000$19605000$@apache.org> MIME-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Mailer: Microsoft Outlook 15.0 Thread-Index: AQGcABAZ+zUAjwXqhneQ+wQSEA5PCAJDAKznAphVvLoCa+XdiQGmDBRumgMv+6A= Content-Language: de Hi Mark, > -----Original Message----- > From: Mark Thomas [mailto:markt@apache.org] > Sent: Friday, October 4, 2013 11:58 PM > To: Tomcat Developers List > Subject: Re: 8.0.x / 7.0.x progress >=20 > On 04/10/2013 22:49, Konstantin Prei=C3=9Fer 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. >=20 > 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). >=20 > 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. > > 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. >=20 > 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). 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=C3=9Fer --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org For additional commands, e-mail: dev-help@tomcat.apache.org