Re: WebSocket progress report
On Mar 7, 2013, at 5:33 PM, Mark Thomas wrote: The current status of the WebSocket implementation is largely complete. The remaining TODOs are (in roughly the order I intend to tackle them): 1. Implement decoding 2. Figure out why there are failures in Autobahn with WSS and NIO and APR/native 3. Run the TCK (as an EG member I have early access to this until 30th April mainly to test the TCK). 4. Implement WSS for the client 5. Fix all the various places where I didn't get around to / forgot to complete the plumbing 6. Read the spec carefully and check the implementation against it 7. Improve HTTP header parsing for the client As always any help is appreciated. Mark Mark, I'm very excited to see the progress you're making on WebSockets. I do have a couple quick questions if you have a second, both related to the fact that in 3-4 days I'll be starting the chapter on WebSockets for my book. 1) I understand that this isn't done, but is it close enough to done that I should be able to write and test simple examples (e.g., the ubiquitous chat example)? 2) I have the spec and javadoc from http://download.oracle.com/otndocs/jcp/websocket-1_0-pr-spec/index.html. If you have a newer one, is it possible to send it to me? Thanks, Nick
Re: WebSocket progress report
On 09/03/2013 15:29, Nick Williams wrote: On Mar 7, 2013, at 5:33 PM, Mark Thomas wrote: The current status of the WebSocket implementation is largely complete. The remaining TODOs are (in roughly the order I intend to tackle them): 1. Implement decoding 2. Figure out why there are failures in Autobahn with WSS and NIO and APR/native 3. Run the TCK (as an EG member I have early access to this until 30th April mainly to test the TCK). 4. Implement WSS for the client 5. Fix all the various places where I didn't get around to / forgot to complete the plumbing 6. Read the spec carefully and check the implementation against it 7. Improve HTTP header parsing for the client As always any help is appreciated. Mark Mark, I'm very excited to see the progress you're making on WebSockets. I do have a couple quick questions if you have a second, both related to the fact that in 3-4 days I'll be starting the chapter on WebSockets for my book. 1) I understand that this isn't done, but is it close enough to done that I should be able to write and test simple examples (e.g., the ubiquitous chat example)? Yes. http://svn.apache.org/viewvc/tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/chat/ChatAnnotation.java?view=annotate I like the snake example. 2) I have the spec and javadoc from http://download.oracle.com/otndocs/jcp/websocket-1_0-pr-spec/index.html. If you have a newer one, is it possible to send it to me? That is the latest. The EG is discussing some minor tweaks and clarifications but that is pretty close to what the final specification will look like. Mark - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
On 21/12/2012 23:13, Mark Thomas wrote: After that, I intend to run the Autobahn test suite and fix any issues that identifies. Passes for BIO and NIO. ~30 failures for APR/native Next step will be to look at making the buffer sizes configurable to address the failures above before moving on to the rest of the test suite. This wasn't necessary. It is implemented and may offer some performance optimisations but is not required for handling of large messages (providing the WebSocket Endpoint will accept partial messages). Once I have something that passes the Autobahn test suite my next set of priorities will be to clean up the code. By that I mean: - consistent formatting - complete the Javadoc - consistent naming conventions - i18n - refactor to reduce duplication - reduce visibility to the minimum require to function correctly The next block of work will be to complete the WebSocket client implementation and then use that to generate unit tests. My aim then will be to go through the API and get as close as practical to 100% code coverage with the unit tests. Alongside all of this will be updating the implementation for changes to the draft specification which may well mean going back several steps. The API is up to date with the latest draft (v11). One reason for concentrating on the different connectors right now is that the less of the API that is implemented, the easier it is to keep up with the changes. Finally, I want to do some performance testing. Some of this may get pulled forward if the Autobahn test suite finds something truly awful (given my approach to date of focussing on getting something that works this is quite likely). No obvious performance issues so far. I'm sure, however, there will be scope for improvement. Help in any form is always appreciated. Mark - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
On 12/12/2012 21:23, Mark Thomas wrote: The next step is to implement support for outgoing messages from server endpoints. Done. Once that is in place, I will update the examples to use the new implementation and fix any issues that identifies. Done. After that, I intend to run the Autobahn test suite and fix any issues that identifies. Pass 1.1.1-1.1.5, 1.2.1-1.2.5 Fail 1.1.6-1.1.8, 1.2.6-1.1.8 (all because server side buffer is too small) Not tested 2 onwards As expected, the Autobahn test suite has already identified numerous issues with the initial implementation as it is far less forgiving than browsers - particularly about ensuring connections are closed cleanly. Next step will be to look at making the buffer sizes configurable to address the failures above before moving on to the rest of the test suite. Once I have something that passes the Autobahn test suite my next set of priorities will be to clean up the code. By that I mean: - consistent formatting - complete the Javadoc - consistent naming conventions - i18n - refactor to reduce duplication - reduce visibility to the minimum require to function correctly The next block of work will be to complete the WebSocket client implementation and then use that to generate unit tests. My aim then will be to go through the API and get as close as practical to 100% code coverage with the unit tests. Alongside all of this will be updating the implementation for changes to the draft specification which may well mean going back several steps. Finally, I want to do some performance testing. Some of this may get pulled forward if the Autobahn test suite finds something truly awful (given my approach to date of focussing on getting something that works this is quite likely). Help in any form is always appreciated. Mark - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
On 23/02/2012 01:32, Petr Praus wrote: On Mon, Feb 20, 2012 at 16:19, Mark Thomas ma...@apache.org wrote: Haven't looked too hard at those yet. Assuming Java can tell the UTF-8 is invalid then handling that should be easy. Yes, except that the java CharsetDecoder didn't seem to think that UTF-8 sent by Autobahn as invalid was indeed invalid. At least was my impression, but I might very well be wrong. Java complains about most of them. I need to dig into the ones it doesn't. Something isn't quite right there yet. There are some of those trunk changes (I am thinking of AbstractProcessor) that you'll need to pull into your fork. I'll try to pull these during the weekend, maybe it'll still be useful. I get the impression that trunk is heading towards your implementation. 'd be happy to look at suggested patches to improve trunk that moved it towards your implementation. As I said before, small incremental changes are easier to manage than one big patch. Mark - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
On Mon, Feb 20, 2012 at 16:19, Mark Thomas ma...@apache.org wrote: On 20/02/2012 21:28, Petr Praus wrote: I'm glad to hear that. BTW, Jonathan quite significantly overhauled our implementation over the weekend. The WebSocketFrame no longer buffers data but just stores a reference to inputstream from which the data can be read by the client code receiving the frame. This is not exactly what you originally implemented but I think it's conceptually the same. That sounds much better (I haven't looked at the code in detail). In the future it would desirable to shield client code from the WebSocketFrame itself and just provide streams. Indeed. That is how the current implementation in trunk works. I personally think of WebSocketFrame as being more useful to internal protocol logic than client code which very often does not care about most of the stuff captured in the frame, just the data. Agree completely. I added some fixes yesterday and the code now passes all Autobahn tests including proper closes and close status codes. Very nice. That is better than the current trunk can manage. The only exception are UTF-8-related tests which require reading whole payload and checking that its valid UTF-8. Haven't looked too hard at those yet. Assuming Java can tell the UTF-8 is invalid then handling that should be easy. Yes, except that the java CharsetDecoder didn't seem to think that UTF-8 sent by Autobahn as invalid was indeed invalid. At least was my impression, but I might very well be wrong. Unfortunately it's no longer easily mergeable with current trunk because of your fragmentation changes on Friday, but if you would be willing to look at it anyway, it's available in our GitHub repository: https://github.com/praus/tomcat (the repository is a fork of the official github apache/tomcat mirror). That is pretty much inevitable when you have a large patch and one of the main reasons I am trying to keep to small incremental changes in trunk. There are some of those trunk changes (I am thinking of AbstractProcessor) that you'll need to pull into your fork. I'll try to pull these during the weekend, maybe it'll still be useful. I am borrowing from your fork where I can and am providing credit in the commit message so you can see what I have used. You'll also get credit in the changelog along with the other folks that have contributed code to the WebSocket impl. Thanks! Based on progress today, things should move along pretty quickly. Next step is to get ping/pong working. Mark Petr On Mon, Feb 20, 2012 at 14:35, Mark Thomas ma...@apache.org wrote: On 20/02/2012 10:04, Mark Thomas wrote: On 20/02/2012 02:55, Petr Praus wrote: but I wanted to ask - have you considered using Autobahn for testing? It's rather extensive opensource websocket testing suite. I haven't. I just took a quick look. Looks like a nice tool. My test client is intended to be something we can run in the unit tests to look at very specific issues. It isn't intended to be a general WebSocket client, nor to test the full range of functionality. I think Autobhan is something we would run separately - a bit like we do with the WebDAV test suite and the TCKs. I've been looking at this today and so far, my experience has been very good. Thanks for the tip. It has been really useful. I now have all the framing tests passing but the message close is currently unclean. Next step will be to fix that by adding support for close. Mark - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
On 20/02/2012 02:55, Petr Praus wrote: Hi Mark, I noticed you wrote a websocket test client, I haven't looked at it extensively It won't take long to look at - it is a very simple client. but I wanted to ask - have you considered using Autobahn for testing? It's rather extensive opensource websocket testing suite. I haven't. I just took a quick look. Looks like a nice tool. My test client is intended to be something we can run in the unit tests to look at very specific issues. It isn't intended to be a general WebSocket client, nor to test the full range of functionality. I think Autobhan is something we would run separately - a bit like we do with the WebDAV test suite and the TCKs. It already contains a lot of stuff we need to test including fragmentation testing. Yep, it looks really good. I dread to think how many failures we'd get with the current code :) What we can do is to provide the necessary servlet that AutoBahn needs to talk to as part of the examples web app. That way, anyone can run the test suite with minimal effort. On Fri, Feb 17, 2012 at 14:50, Mark Thomas ma...@apache.org wrote: On 16/02/2012 04:01, Petr Praus wrote: Hello, attached is our patch. It applies cleanly on top of current trunk rev. 1244719. It has rudimentary support for fragmentation (callback after last frame), supports close messages and ping/pong. Sorry for not sending a patchset but I thought it wouldn't really make sense, since there were quite a lot of back and forth changes. Let me know if I should send a patchset instead. The final diff is fine to work with from my point of view. (Jonathan's summary) Echoing fragments. Close messages. Pings/pongs. Just barely works. :) Fragmentation support is very limited: a mere callback when last frame received. Repeating what I already wrote in BZ on fragmentation so there is a complete set of review comments in one place I am extremely reluctant to apply the current fragmentation patch. It relies on buffering individual fragments and - given the maximum fragment size - that is simply not going to scale. This is why the current API is built on streams and does not buffer unless the message based API is used. I'd like to fully explore the possibility of supporting fragments without using buffering before starting down that path. I understand your concern, the main idea was that the logic that pertains only to a single frame and the information about the frame itself should be encapsulated there. What about letting the client code know there's a new frame before we begin reading the data but still keep the frames encapsulated in WebSocketFrame? Getting fragmentation support working with streams was easier than I expected. Essentially, just pushing the frame header processing code down into the InputStream was all that was required. I prefer the approach where the client gets one notification per 'message' rather than per frame. Need up is handling the control messages. Mark - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
On 20/02/2012 10:04, Mark Thomas wrote: On 20/02/2012 02:55, Petr Praus wrote: but I wanted to ask - have you considered using Autobahn for testing? It's rather extensive opensource websocket testing suite. I haven't. I just took a quick look. Looks like a nice tool. My test client is intended to be something we can run in the unit tests to look at very specific issues. It isn't intended to be a general WebSocket client, nor to test the full range of functionality. I think Autobhan is something we would run separately - a bit like we do with the WebDAV test suite and the TCKs. I've been looking at this today and so far, my experience has been very good. Thanks for the tip. It has been really useful. I now have all the framing tests passing but the message close is currently unclean. Next step will be to fix that by adding support for close. Mark - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
I'm glad to hear that. BTW, Jonathan quite significantly overhauled our implementation over the weekend. The WebSocketFrame no longer buffers data but just stores a reference to inputstream from which the data can be read by the client code receiving the frame. This is not exactly what you originally implemented but I think it's conceptually the same. In the future it would desirable to shield client code from the WebSocketFrame itself and just provide streams. I personally think of WebSocketFrame as being more useful to internal protocol logic than client code which very often does not care about most of the stuff captured in the frame, just the data. I added some fixes yesterday and the code now passes all Autobahn tests including proper closes and close status codes. The only exception are UTF-8-related tests which require reading whole payload and checking that its valid UTF-8. Unfortunately it's no longer easily mergeable with current trunk because of your fragmentation changes on Friday, but if you would be willing to look at it anyway, it's available in our GitHub repository: https://github.com/praus/tomcat (the repository is a fork of the official github apache/tomcat mirror). Petr On Mon, Feb 20, 2012 at 14:35, Mark Thomas ma...@apache.org wrote: On 20/02/2012 10:04, Mark Thomas wrote: On 20/02/2012 02:55, Petr Praus wrote: but I wanted to ask - have you considered using Autobahn for testing? It's rather extensive opensource websocket testing suite. I haven't. I just took a quick look. Looks like a nice tool. My test client is intended to be something we can run in the unit tests to look at very specific issues. It isn't intended to be a general WebSocket client, nor to test the full range of functionality. I think Autobhan is something we would run separately - a bit like we do with the WebDAV test suite and the TCKs. I've been looking at this today and so far, my experience has been very good. Thanks for the tip. It has been really useful. I now have all the framing tests passing but the message close is currently unclean. Next step will be to fix that by adding support for close. Mark - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
On 20/02/2012 21:28, Petr Praus wrote: I'm glad to hear that. BTW, Jonathan quite significantly overhauled our implementation over the weekend. The WebSocketFrame no longer buffers data but just stores a reference to inputstream from which the data can be read by the client code receiving the frame. This is not exactly what you originally implemented but I think it's conceptually the same. That sounds much better (I haven't looked at the code in detail). In the future it would desirable to shield client code from the WebSocketFrame itself and just provide streams. Indeed. That is how the current implementation in trunk works. I personally think of WebSocketFrame as being more useful to internal protocol logic than client code which very often does not care about most of the stuff captured in the frame, just the data. Agree completely. I added some fixes yesterday and the code now passes all Autobahn tests including proper closes and close status codes. Very nice. That is better than the current trunk can manage. The only exception are UTF-8-related tests which require reading whole payload and checking that its valid UTF-8. Haven't looked too hard at those yet. Assuming Java can tell the UTF-8 is invalid then handling that should be easy. Unfortunately it's no longer easily mergeable with current trunk because of your fragmentation changes on Friday, but if you would be willing to look at it anyway, it's available in our GitHub repository: https://github.com/praus/tomcat (the repository is a fork of the official github apache/tomcat mirror). That is pretty much inevitable when you have a large patch and one of the main reasons I am trying to keep to small incremental changes in trunk. There are some of those trunk changes (I am thinking of AbstractProcessor) that you'll need to pull into your fork. I am borrowing from your fork where I can and am providing credit in the commit message so you can see what I have used. You'll also get credit in the changelog along with the other folks that have contributed code to the WebSocket impl. Based on progress today, things should move along pretty quickly. Next step is to get ping/pong working. Mark Petr On Mon, Feb 20, 2012 at 14:35, Mark Thomas ma...@apache.org wrote: On 20/02/2012 10:04, Mark Thomas wrote: On 20/02/2012 02:55, Petr Praus wrote: but I wanted to ask - have you considered using Autobahn for testing? It's rather extensive opensource websocket testing suite. I haven't. I just took a quick look. Looks like a nice tool. My test client is intended to be something we can run in the unit tests to look at very specific issues. It isn't intended to be a general WebSocket client, nor to test the full range of functionality. I think Autobhan is something we would run separately - a bit like we do with the WebDAV test suite and the TCKs. I've been looking at this today and so far, my experience has been very good. Thanks for the tip. It has been really useful. I now have all the framing tests passing but the message close is currently unclean. Next step will be to fix that by adding support for close. Mark - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
On 20/02/2012 22:19, Mark Thomas wrote: Based on progress today, things should move along pretty quickly. Next step is to get ping/pong working. Yep. Progress has been pretty quick. Ping/pong tests (section 2) now all pass as do sections 3 (reserved bits) and 4 (opcodes). There are a few failures in section 5 (fragmentation) and they are due to not handling control frames in the middle of fragmented messages. Hopefully fixing that will mostly just be a little refactoring - pushing more stuff down into the WsInputStream. I plan to look at that tomorrow although I need to do the 7.0.26 release first. Mark - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
Hi Mark, I noticed you wrote a websocket test client, I haven't looked at it extensively but I wanted to ask - have you considered using Autobahn for testing? It's rather extensive opensource websocket testing suite. It already contains a lot of stuff we need to test including fragmentation testing. On Fri, Feb 17, 2012 at 14:50, Mark Thomas ma...@apache.org wrote: On 16/02/2012 04:01, Petr Praus wrote: Hello, attached is our patch. It applies cleanly on top of current trunk rev. 1244719. It has rudimentary support for fragmentation (callback after last frame), supports close messages and ping/pong. Sorry for not sending a patchset but I thought it wouldn't really make sense, since there were quite a lot of back and forth changes. Let me know if I should send a patchset instead. The final diff is fine to work with from my point of view. (Jonathan's summary) Echoing fragments. Close messages. Pings/pongs. Just barely works. :) Fragmentation support is very limited: a mere callback when last frame received. Repeating what I already wrote in BZ on fragmentation so there is a complete set of review comments in one place I am extremely reluctant to apply the current fragmentation patch. It relies on buffering individual fragments and - given the maximum fragment size - that is simply not going to scale. This is why the current API is built on streams and does not buffer unless the message based API is used. I'd like to fully explore the possibility of supporting fragments without using buffering before starting down that path. I understand your concern, the main idea was that the logic that pertains only to a single frame and the information about the frame itself should be encapsulated there. What about letting the client code know there's a new frame before we begin reading the data but still keep the frames encapsulated in WebSocketFrame? Sends normal closing reply messages and some protocol error closes. Answers pings with pongs. The fragmentation implementation is likely to impact how this is done, so I'd like to resolve that issue first and then come back to this. Moving towards a better application API. I think I know what you mean by this but please could you explain in more detail. The servlet container is doing something I don't understand with rapid connection attempts…not sure what's up. Tell us what you observe and we might be able to explain it. I renamed StreamInbound to WebSocketConnection since it's bidirectional. This looks to be related to the refactoring. I'm more worried about design and features than I am naming right now. Also I gave the upgrade processors close() methods. That isn't how socket closure needs to be managed. You'll get away with it with BIO but things are very likely blow up (with a JVM core) when you do that with APR. You need to let the surrounding Protocol handle that by returning the correct socket state. Fixed a number of bugs, including Please enumerate all the bugs you fixed so I can ensure that part of the patch is pulled forward ASAP. a switch statement with accidentally cascading cases, That looks to be deliberate to me, although a bunch of TODOs wouldn't have hurt. This was actually a bug in my code in WebSocketFrame, it wasn't deliberate :) and a problem with in Conversions.byteArrayToLong(). Thanks. Fixed. General comment: The code style of a patch needs to be consistent with the Tomcat code style. Braces on a new line is the obvious thing that jumped out at me as I read the patch. Actually, this looks to be confined to a single class. Thanks for the comment, we'll try to keep it consistent. Yes, I know the Tomcat code base isn't internally consistent style wise. The code is 10+ years old and it shows. Use the code in the current websocket package as a basis. - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
On 16/02/2012 04:01, Petr Praus wrote: Hello, attached is our patch. It applies cleanly on top of current trunk rev. 1244719. It has rudimentary support for fragmentation (callback after last frame), supports close messages and ping/pong. Sorry for not sending a patchset but I thought it wouldn't really make sense, since there were quite a lot of back and forth changes. Let me know if I should send a patchset instead. The final diff is fine to work with from my point of view. (Jonathan's summary) Echoing fragments. Close messages. Pings/pongs. Just barely works. :) Fragmentation support is very limited: a mere callback when last frame received. Repeating what I already wrote in BZ on fragmentation so there is a complete set of review comments in one place I am extremely reluctant to apply the current fragmentation patch. It relies on buffering individual fragments and - given the maximum fragment size - that is simply not going to scale. This is why the current API is built on streams and does not buffer unless the message based API is used. I'd like to fully explore the possibility of supporting fragments without using buffering before starting down that path. Sends normal closing reply messages and some protocol error closes. Answers pings with pongs. The fragmentation implementation is likely to impact how this is done, so I'd like to resolve that issue first and then come back to this. Moving towards a better application API. I think I know what you mean by this but please could you explain in more detail. The servlet container is doing something I don't understand with rapid connection attempts…not sure what's up. Tell us what you observe and we might be able to explain it. I renamed StreamInbound to WebSocketConnection since it's bidirectional. This looks to be related to the refactoring. I'm more worried about design and features than I am naming right now. Also I gave the upgrade processors close() methods. That isn't how socket closure needs to be managed. You'll get away with it with BIO but things are very likely blow up (with a JVM core) when you do that with APR. You need to let the surrounding Protocol handle that by returning the correct socket state. Fixed a number of bugs, including Please enumerate all the bugs you fixed so I can ensure that part of the patch is pulled forward ASAP. a switch statement with accidentally cascading cases, That looks to be deliberate to me, although a bunch of TODOs wouldn't have hurt. and a problem with in Conversions.byteArrayToLong(). Thanks. Fixed. General comment: The code style of a patch needs to be consistent with the Tomcat code style. Braces on a new line is the obvious thing that jumped out at me as I read the patch. Actually, this looks to be confined to a single class. Yes, I know the Tomcat code base isn't internally consistent style wise. The code is 10+ years old and it shows. Use the code in the current websocket package as a basis. - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
Thanks Johno Crawford for pointing out that attachments are stripped, I uploaded the patch here: https://gist.github.com/1844837 On Wed, Feb 15, 2012 at 22:01, Petr Praus p...@praus.net wrote: Hello, attached is our patch. It applies cleanly on top of current trunk rev. 1244719. It has rudimentary support for fragmentation (callback after last frame), supports close messages and ping/pong. Sorry for not sending a patchset but I thought it wouldn't really make sense, since there were quite a lot of back and forth changes. Let me know if I should send a patchset instead. (Jonathan's summary) Echoing fragments. Close messages. Pings/pongs. Just barely works. :) Fragmentation support is very limited: a mere callback when last frame received. Sends normal closing reply messages and some protocol error closes. Answers pings with pongs. Moving towards a better application API. The servlet container is doing something I don't understand with rapid connection attempts…not sure what's up. I renamed StreamInbound to WebSocketConnection since it's bidirectional. Also I gave the upgrade processors close() methods. Fixed a number of bugs, including a switch statement with accidentally cascading cases, and a problem with in Conversions.byteArrayToLong(). Thanks, Petr On Wed, Feb 15, 2012 at 17:17, Petr Praus p...@praus.net wrote: Hi, sorry for the delay, we got stalled a little bit, I'll post the patch today (US central time) after I manage to merge it (oh the cursed newlines). Thanks, Petr On Mon, Feb 13, 2012 at 14:18, Christopher Schultz ch...@christopherschultz.net wrote: Jeremy, On 2/10/12 12:08 PM, Jeremy Brown wrote: I suspect it will need more than that. The XLST will almost certainly need some tweaks too. How timely, I'm doing xml transformations in my SOA class right now. If you have any questions about XSLT, I'd be happy to answer them. It's definitely something that you have to have a Zenlike relationship with in order to do properly. Just like Lisp, it's possible to write really awful procedurally-oriented code with it, but then it just sucks horribly. We've been using XSLT for a long time with Apache Cocoon (such a great product) to transform XML into XHTML. I'd be happy to help. -chris
Re: WebSocket progress report
Hi, sorry for the delay, we got stalled a little bit, I'll post the patch today (US central time) after I manage to merge it (oh the cursed newlines). Thanks, Petr On Mon, Feb 13, 2012 at 14:18, Christopher Schultz ch...@christopherschultz.net wrote: Jeremy, On 2/10/12 12:08 PM, Jeremy Brown wrote: I suspect it will need more than that. The XLST will almost certainly need some tweaks too. How timely, I'm doing xml transformations in my SOA class right now. If you have any questions about XSLT, I'd be happy to answer them. It's definitely something that you have to have a Zenlike relationship with in order to do properly. Just like Lisp, it's possible to write really awful procedurally-oriented code with it, but then it just sucks horribly. We've been using XSLT for a long time with Apache Cocoon (such a great product) to transform XML into XHTML. I'd be happy to help. -chris
Re: WebSocket progress report
Hello, attached is our patch. It applies cleanly on top of current trunk rev. 1244719. It has rudimentary support for fragmentation (callback after last frame), supports close messages and ping/pong. Sorry for not sending a patchset but I thought it wouldn't really make sense, since there were quite a lot of back and forth changes. Let me know if I should send a patchset instead. (Jonathan's summary) Echoing fragments. Close messages. Pings/pongs. Just barely works. :) Fragmentation support is very limited: a mere callback when last frame received. Sends normal closing reply messages and some protocol error closes. Answers pings with pongs. Moving towards a better application API. The servlet container is doing something I don't understand with rapid connection attempts…not sure what's up. I renamed StreamInbound to WebSocketConnection since it's bidirectional. Also I gave the upgrade processors close() methods. Fixed a number of bugs, including a switch statement with accidentally cascading cases, and a problem with in Conversions.byteArrayToLong(). Thanks, Petr On Wed, Feb 15, 2012 at 17:17, Petr Praus p...@praus.net wrote: Hi, sorry for the delay, we got stalled a little bit, I'll post the patch today (US central time) after I manage to merge it (oh the cursed newlines). Thanks, Petr On Mon, Feb 13, 2012 at 14:18, Christopher Schultz ch...@christopherschultz.net wrote: Jeremy, On 2/10/12 12:08 PM, Jeremy Brown wrote: I suspect it will need more than that. The XLST will almost certainly need some tweaks too. How timely, I'm doing xml transformations in my SOA class right now. If you have any questions about XSLT, I'd be happy to answer them. It's definitely something that you have to have a Zenlike relationship with in order to do properly. Just like Lisp, it's possible to write really awful procedurally-oriented code with it, but then it just sucks horribly. We've been using XSLT for a long time with Apache Cocoon (such a great product) to transform XML into XHTML. I'd be happy to help. -chris - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
Mark, On 2/10/12 11:49 AM, Mark Thomas wrote: I prefer the work pid did on the Tomcat 7 index page for the ROOT webapp. +1 -chris signature.asc Description: OpenPGP digital signature
Re: WebSocket progress report
Jeremy, On 2/10/12 12:08 PM, Jeremy Brown wrote: I suspect it will need more than that. The XLST will almost certainly need some tweaks too. How timely, I'm doing xml transformations in my SOA class right now. If you have any questions about XSLT, I'd be happy to answer them. It's definitely something that you have to have a Zenlike relationship with in order to do properly. Just like Lisp, it's possible to write really awful procedurally-oriented code with it, but then it just sucks horribly. We've been using XSLT for a long time with Apache Cocoon (such a great product) to transform XML into XHTML. I'd be happy to help. -chris signature.asc Description: OpenPGP digital signature
Re: WebSocket progress report
Hi Mark, I think I can work on the website. Is it mostly a css refresh you are speaking of? Are there new features that are needed? I like the look of the apache mina site http://mina.apache.org/ with the soft edges, gradients and nice spacing. Is there any php in the webpage source or is it just html? Cheers, Jeremy On Thu, Feb 9, 2012 at 10:04 AM, Mark Thomas ma...@apache.org wrote: On 09/02/2012 15:07, Jeremy brown wrote: Hi Jonathan and Petr, I'm an Application Development Graduate Student at Illinois Institute of Technology and I'd like to get started contributing to Tomcat. If you have any tasks I can help out with please let me know. I'd even be happy to start with simple tasks in order begin to familiarize myself with the project and code base, such as writing or formatting javadoc or cleaning up white space. Cheers, Jeremy Jeremy, In addition to the WebSocket work, there are ~100 enhancement requests in various states in Bugzilla. You could also take a look at those and see if one sparks your interest. If you have an interest in web design the the Tomcat web site and documentation is long overdue an overhaul. Mark - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
On 10/02/2012 16:06, Jeremy Brown wrote: Hi Mark, I think I can work on the website. Is it mostly a css refresh you are speaking of? I suspect it will need more than that. The XLST will almost certainly need some tweaks too. Are there new features that are needed? I don't think so. I like the look of the apache mina site http://mina.apache.org/ with the soft edges, gradients and nice spacing. I prefer the work pid did on the Tomcat 7 index page for the ROOT webapp. Is there any php in the webpage source or is it just html? The website needs to be static with the exception of the download pages that use a little cgi. Mark - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
Hi Mark, I suspect it will need more than that. The XLST will almost certainly need some tweaks too. How timely, I'm doing xml transformations in my SOA class right now. I prefer the work pid did on the Tomcat 7 index page for the ROOT webapp. I haven't used 7 yet, only 5 and 6. But I would agree on principle that the looks between these two entities should match. I should have some time this weekend to install tomcat 7 and take a look. Cheers, Jeremy On Fri, Feb 10, 2012 at 10:49 AM, Mark Thomas ma...@apache.org wrote: On 10/02/2012 16:06, Jeremy Brown wrote: Hi Mark, I think I can work on the website. Is it mostly a css refresh you are speaking of? I suspect it will need more than that. The XLST will almost certainly need some tweaks too. Are there new features that are needed? I don't think so. I like the look of the apache mina site http://mina.apache.org/ with the soft edges, gradients and nice spacing. I prefer the work pid did on the Tomcat 7 index page for the ROOT webapp. Is there any php in the webpage source or is it just html? The website needs to be static with the exception of the download pages that use a little cgi. Mark - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
Hi, I haven't communicated with you yet, but I am from the same team as Petr and Jonathan. This is a list of what we have done. We need to clean the code, but we will send a patch tomorrow. So far we started with incoming communation, sending was not done yet. We created two levels of abstraction of frames: 1) WebSocketFrame, which is responsible for handling bits and bytes, translation to/from fields, detects protocol errors (detectable without any further context) //per frame 2) represented by StreamInbound - messege-wise logic - handles fragmentation, interprets fields, detects protocol errors based on message context //per message We actually implemented fragmentation, detecting of control frames, control frames inside fragmented messages. Btw. we decided to signal end of a message via a method call rather than calling on...Data with empty stream/reader. Still TODO about receiveing: 1) protocol errors 2) handling control frames (connection state needed = third level of abstraction //per connection) 3) large messages (this should be minor refactoring) 4) further improvements of WebSocketFrame, I think this class will be changing a lot Application point of view: EchoStream shows some ideas on streaming approach and multiple theads. We plant to do next: large messages, handling of control frames (this will unevitable touch sending), some facade API (since extending two classes and using third one is a pain) Slavka - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
Hi Jonathan and Petr, I'm an Application Development Graduate Student at Illinois Institute of Technology and I'd like to get started contributing to Tomcat. If you have any tasks I can help out with please let me know. I'd even be happy to start with simple tasks in order begin to familiarize myself with the project and code base, such as writing or formatting javadoc or cleaning up white space. Cheers, Jeremy On Wed, Feb 8, 2012 at 8:41 PM, Petr Praus p...@praus.net wrote: On Tue, Feb 7, 2012 at 03:47, Mark Thomas ma...@apache.org wrote: On 07/02/2012 02:23, Jonathan Drake wrote: I'm one the three CS grad students working on WebSocket (along with Petr Praus). Just wanted to give an update on our progress, to let you know what we're working on: Adding support for fragmented payloads: Excellent. That and handling control frames are the biggest gaps right now in my view. Right now, after receiving a frame, StreamInbound unmasks the payload in a WsInputStream and passes it up to the servlet via onBinaryData()/onTextData(). To support fragmented frames, we add an intermediate step: after unmasking the payload, write it to a PipedOutputStream connected to a PipedInputStream that we pass upward via onBinaryData()/onTextData(). When the next fragment arrives, keep streaming data through the pipe. Piped[Input|Output]Stream are intended to be used with a separate thread at each end. There is currently only a single thread processing the incoming data. How do you propose to provide the additional thread? Ah, then it's different. I thought the client handler is running in different thread. Then we'll probably need something different. This has the advantage of also allowing us to stream huge payloads (RFC 6455 allows for a 64-bit extended length field---way too much data to buffer in memory all at once). That is certainly a requirement. However, there is more than one way to meet that requirement. Our initial idea was some form of a streaming API where the reader code receiving the message fills a stream that's somehow connected to a client code that would be consuming it. Hence the Piped[Input|Output]Stream stuff. I also think the individual frames of a fragmented messages should not be exposed to the client code. If I remember correctly, RFC specifies that its up to the implementation to decide. What do you think? And, what are your other ideas for supporting huge payloads? It has the minor disadvantage of breaking the ByteBuffer wrappers from MessageInbound (we can still use them for small payloads if we buffer fragments in memory) Could you clarify what is broken in what circumstances please. MessageInbound is expected to work providing that the message (regardless of how many fragments it is spread across) is smaller than the available buffer size. My expectation is that the current echo example would continue to work regardless of whether or not the messages were in a single fragment or multiple fragments. I'm working on a patch that implements this...maybe a day or two. I'd appreciate any early criticism you may have---otherwise I mainly just want to prevent duplicate work by explaining what we're up to. Thanks for the heads up. The approach you describe isn't the one I had in mind, but that is a good thing. It provides an opportunity to compare and to take the best from both. It would be nice to have a test case or an example client for this. Unless there is an easy way to force a browser to fragment packets, I suspect a test case will be required. I'm not sure about other browsers but Chrome 16 fragments payloads so that WS frames fit into MSS of the underlying protocol (TCP). So if I sent string larger than roughly 1450 bytes from the client javascript, I got fragments packets. Beware that lo device on Linux has by default MTU 16436 so on localhost, the above value of 1450 bytes is much larger. Given that the implementation currently uses blocking IO Just to make sure, processor.read() calls are always blocking, right? I'm somewhat confused by Nio/Bio/Apr in combination with this. As I understand it, any of the three can be used at the user's will and so the processor can be of type UpgradeNioProcessor. In that case the read on the underlying socket is not blocking. So how come read on the UpgradeProcessor will always be blocking? Can you shed some light on this? Thanks , my approach was going to be something along the lines of: a) read the headers b) call onBinaryData() / onTextData() c) make the payload available via WsInputStream until the end of the fragment d) read the headers for the next fragment e) make the payload available via WsInputStream until the end of the fragment f) repeat d) e) until the final fragment is processed g) return EOF on the next read This would mean moving
Re: WebSocket progress report
On 09/02/2012 02:41, Petr Praus wrote: Our initial idea was some form of a streaming API where the reader code receiving the message fills a stream that's somehow connected to a client code that would be consuming it. Hence the Piped[Input|Output]Stream stuff. I also think the individual frames of a fragmented messages should not be exposed to the client code. If I remember correctly, RFC specifies that its up to the implementation to decide. What do you think? I agree. And, what are your other ideas for supporting huge payloads? Streaming is the only (scalable / efficient) game in town for that. I'm not sure about other browsers but Chrome 16 fragments payloads so that WS frames fit into MSS of the underlying protocol (TCP). So if I sent string larger than roughly 1450 bytes from the client javascript, I got fragments packets. Beware that lo device on Linux has by default MTU 16436 so on localhost, the above value of 1450 bytes is much larger. Ah. Interesting. That could be very useful. Given that the implementation currently uses blocking IO Just to make sure, processor.read() calls are always blocking, right? I assume you mean UpgradeProcessor.read() rather than Processor.read() (which doesn't exist). Yes, UpgradeProcessor.read() is (currently) always blocking. I'm somewhat confused by Nio/Bio/Apr in combination with this. As I understand it, any of the three can be used at the user's will and so the processor can be of type UpgradeNioProcessor. In that case the read on the underlying socket is not blocking. Yes it is. It is performed using a blocking Selector. The parameter is there to allow non-blocking reads but that makes the whole API a lot more complicated so it is currently on the We'll look at implementing it a) if there is a demand for it and b) we can come up with a sane API category. So how come read on the UpgradeProcessor will always be blocking? Can you shed some light on this? Thanks Take a look at UpgradeNioProcessor.readSocket() and the value of the block parameter whenever that method is called. my approach was going to be something along the lines of: a) read the headers b) call onBinaryData() / onTextData() c) make the payload available via WsInputStream until the end of the fragment d) read the headers for the next fragment e) make the payload available via WsInputStream until the end of the fragment f) repeat d) e) until the final fragment is processed g) return EOF on the next read This would mean moving most of the code currently in StreamInBound.onData() to WsInputStream I haven't tried coding this up or anything so there is no guarantee it would actually work. This seems like a sensible approach, I'll look into it. Sounds good. Mark - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
On 09/02/2012 15:07, Jeremy brown wrote: Hi Jonathan and Petr, I'm an Application Development Graduate Student at Illinois Institute of Technology and I'd like to get started contributing to Tomcat. If you have any tasks I can help out with please let me know. I'd even be happy to start with simple tasks in order begin to familiarize myself with the project and code base, such as writing or formatting javadoc or cleaning up white space. Cheers, Jeremy Jeremy, In addition to the WebSocket work, there are ~100 enhancement requests in various states in Bugzilla. You could also take a look at those and see if one sparks your interest. If you have an interest in web design the the Tomcat web site and documentation is long overdue an overhaul. Mark - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
On Tue, Feb 7, 2012 at 03:47, Mark Thomas ma...@apache.org wrote: On 07/02/2012 02:23, Jonathan Drake wrote: I'm one the three CS grad students working on WebSocket (along with Petr Praus). Just wanted to give an update on our progress, to let you know what we're working on: Adding support for fragmented payloads: Excellent. That and handling control frames are the biggest gaps right now in my view. Right now, after receiving a frame, StreamInbound unmasks the payload in a WsInputStream and passes it up to the servlet via onBinaryData()/onTextData(). To support fragmented frames, we add an intermediate step: after unmasking the payload, write it to a PipedOutputStream connected to a PipedInputStream that we pass upward via onBinaryData()/onTextData(). When the next fragment arrives, keep streaming data through the pipe. Piped[Input|Output]Stream are intended to be used with a separate thread at each end. There is currently only a single thread processing the incoming data. How do you propose to provide the additional thread? Ah, then it's different. I thought the client handler is running in different thread. Then we'll probably need something different. This has the advantage of also allowing us to stream huge payloads (RFC 6455 allows for a 64-bit extended length field---way too much data to buffer in memory all at once). That is certainly a requirement. However, there is more than one way to meet that requirement. Our initial idea was some form of a streaming API where the reader code receiving the message fills a stream that's somehow connected to a client code that would be consuming it. Hence the Piped[Input|Output]Stream stuff. I also think the individual frames of a fragmented messages should not be exposed to the client code. If I remember correctly, RFC specifies that its up to the implementation to decide. What do you think? And, what are your other ideas for supporting huge payloads? It has the minor disadvantage of breaking the ByteBuffer wrappers from MessageInbound (we can still use them for small payloads if we buffer fragments in memory) Could you clarify what is broken in what circumstances please. MessageInbound is expected to work providing that the message (regardless of how many fragments it is spread across) is smaller than the available buffer size. My expectation is that the current echo example would continue to work regardless of whether or not the messages were in a single fragment or multiple fragments. I'm working on a patch that implements this...maybe a day or two. I'd appreciate any early criticism you may have---otherwise I mainly just want to prevent duplicate work by explaining what we're up to. Thanks for the heads up. The approach you describe isn't the one I had in mind, but that is a good thing. It provides an opportunity to compare and to take the best from both. It would be nice to have a test case or an example client for this. Unless there is an easy way to force a browser to fragment packets, I suspect a test case will be required. I'm not sure about other browsers but Chrome 16 fragments payloads so that WS frames fit into MSS of the underlying protocol (TCP). So if I sent string larger than roughly 1450 bytes from the client javascript, I got fragments packets. Beware that lo device on Linux has by default MTU 16436 so on localhost, the above value of 1450 bytes is much larger. Given that the implementation currently uses blocking IO Just to make sure, processor.read() calls are always blocking, right? I'm somewhat confused by Nio/Bio/Apr in combination with this. As I understand it, any of the three can be used at the user's will and so the processor can be of type UpgradeNioProcessor. In that case the read on the underlying socket is not blocking. So how come read on the UpgradeProcessor will always be blocking? Can you shed some light on this? Thanks , my approach was going to be something along the lines of: a) read the headers b) call onBinaryData() / onTextData() c) make the payload available via WsInputStream until the end of the fragment d) read the headers for the next fragment e) make the payload available via WsInputStream until the end of the fragment f) repeat d) e) until the final fragment is processed g) return EOF on the next read This would mean moving most of the code currently in StreamInBound.onData() to WsInputStream I haven't tried coding this up or anything so there is no guarantee it would actually work. This seems like a sensible approach, I'll look into it. Petr
Re: WebSocket progress report
On 07/02/2012 02:23, Jonathan Drake wrote: I'm one the three CS grad students working on WebSocket (along with Petr Praus). Just wanted to give an update on our progress, to let you know what we're working on: Adding support for fragmented payloads: Excellent. That and handling control frames are the biggest gaps right now in my view. Right now, after receiving a frame, StreamInbound unmasks the payload in a WsInputStream and passes it up to the servlet via onBinaryData()/onTextData(). To support fragmented frames, we add an intermediate step: after unmasking the payload, write it to a PipedOutputStream connected to a PipedInputStream that we pass upward via onBinaryData()/onTextData(). When the next fragment arrives, keep streaming data through the pipe. Piped[Input|Output]Stream are intended to be used with a separate thread at each end. There is currently only a single thread processing the incoming data. How do you propose to provide the additional thread? This has the advantage of also allowing us to stream huge payloads (RFC 6455 allows for a 64-bit extended length field---way too much data to buffer in memory all at once). That is certainly a requirement. However, there is more than one way to meet that requirement. It has the minor disadvantage of breaking the ByteBuffer wrappers from MessageInbound (we can still use them for small payloads if we buffer fragments in memory) Could you clarify what is broken in what circumstances please. MessageInbound is expected to work providing that the message (regardless of how many fragments it is spread across) is smaller than the available buffer size. My expectation is that the current echo example would continue to work regardless of whether or not the messages were in a single fragment or multiple fragments. I'm working on a patch that implements this...maybe a day or two. I'd appreciate any early criticism you may have---otherwise I mainly just want to prevent duplicate work by explaining what we're up to. Thanks for the heads up. The approach you describe isn't the one I had in mind, but that is a good thing. It provides an opportunity to compare and to take the best from both. It would be nice to have a test case or an example client for this. Unless there is an easy way to force a browser to fragment packets, I suspect a test case will be required. Given that the implementation currently uses blocking IO, my approach was going to be something along the lines of: a) read the headers b) call onBinaryData() / onTextData() c) make the payload available via WsInputStream until the end of the fragment d) read the headers for the next fragment e) make the payload available via WsInputStream until the end of the fragment f) repeat d) e) until the final fragment is processed g) return EOF on the next read This would mean moving most of the code currently in StreamInBound.onData() to WsInputStream I haven't tried coding this up or anything so there is no guarantee it would actually work. Cheers, Mark - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
I'm one the three CS grad students working on WebSocket (along with Petr Praus). Just wanted to give an update on our progress, to let you know what we're working on: Adding support for fragmented payloads: Right now, after receiving a frame, StreamInbound unmasks the payload in a WsInputStream and passes it up to the servlet via onBinaryData()/onTextData(). To support fragmented frames, we add an intermediate step: after unmasking the payload, write it to a PipedOutputStream connected to a PipedInputStream that we pass upward via onBinaryData()/onTextData(). When the next fragment arrives, keep streaming data through the pipe. This has the advantage of also allowing us to stream huge payloads (RFC 6455 allows for a 64-bit extended length field---way too much data to buffer in memory all at once). It has the minor disadvantage of breaking the ByteBuffer wrappers from MessageInbound (we can still use them for small payloads if we buffer fragments in memory) I'm working on a patch that implements this...maybe a day or two. I'd appreciate any early criticism you may have---otherwise I mainly just want to prevent duplicate work by explaining what we're up to. Cheers, Jonathan Drake
Re: WebSocket progress report
Hello, we're group of three CS grad students taking a course in advanced networking. As a course project, each of us has implemented a basic websocket server in Java with functionality roughly equal to the current state of Mark's patch. The next stage of the project is to continue in a group and get the implementation as far as possible. Since building our own standalone websocket server (that does just websocket) doesn't really make sense, we'd like to join in the effort to make websocket available in Tomcat. We've a few questions: 1) Is there an interest in our help? 2) What are the priority TODOs we should start considering? 3) Some examples (e.g. echo server) of how to use the current implementation to write a servlet would be nice. It'd help us to get up to speed more quickly. Also, please note that although this is a course project sanctioned by the professor, we're not really doing this as a course requirement but rather out of our personal interest in contributing to open source. The scope of the class project is 2-3 weeks but that of course doesn't mean we'll abandon the code after that :) Thanks, Petr Praus
Re: WebSocket progress report
On 01/02/2012 21:57, Petr Praus wrote: Hello, we're group of three CS grad students taking a course in advanced networking. As a course project, each of us has implemented a basic websocket server in Java with functionality roughly equal to the current state of Mark's patch. The next stage of the project is to continue in a group and get the implementation as far as possible. Since building our own standalone websocket server (that does just websocket) doesn't really make sense, we'd like to join in the effort to make websocket available in Tomcat. We've a few questions: 1) Is there an interest in our help? Absolutely. 2) What are the priority TODOs we should start considering? See [1]. In my view the priority is: - handle the other control messages - especially close. - handle multi-frame messages then - follow-up on Costin's comments re a lighter-weight approach of wrapping the socket - more and better examples - a lot more JavaDoc - let the API bed down a little and then talk to Jetty about possibly aligning APIs 3) Some examples (e.g. echo server) of how to use the current implementation to write a servlet would be nice. It'd help us to get up to speed more quickly. See [2]. Two very simple examples that need some expansion but it should give you the general idea. Also, please note that although this is a course project sanctioned by the professor, we're not really doing this as a course requirement but rather out of our personal interest in contributing to open source. The scope of the class project is 2-3 weeks but that of course doesn't mean we'll abandon the code after that :) Glad to hear it :) Kind regards, Mark [1] http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java?view=annotate [2] http://svn.apache.org/viewvc/tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/ - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
On 29/01/2012 01:20, Costin Manolache wrote: On Fri, Jan 27, 2012 at 3:09 PM, Mark Thomas ma...@apache.org wrote: Not complaining - it's great to add this feature, please commit it - but I'm wondering if a lighter interface wouldn't be better. From looking at the implementation, it seems after the upgrade it keeps the InputBuffer/OutputBuffer ( and the whole Request / Processor / etc tree ). I agree there is certainly scope to do that. My initial focus has been on functionality and minimal changes to existing code - hence the current approach. I'm not overly keen on the additional overhead myself and can see several ways to reduce it. Output is easier than input since we know the output buffers are clear on upgrade. Input is a little trickier since there may be some data in the input buffer and that would need to be drained before switching to the lighter weight approach. I think this is something to look at once the implementation is more feature complete. Whatever we do, I'd like to keep the following aims in mind: - minimal endpoint specific code - minimal changes to what we have now - keep the generic upgrade and the protocol specific parts separate Would it be possible for example to release the Request, like it's done after request, in keep-alive, and use a lighter parser/callback on the socket ? I think one of the use cases for websockets is to support a _lot_ of open connections. That is certainly one approach. It will be easier to explore options when we have a wider range of examples to work / test with. Also the interface may be simpler without InputStreams. I thought long and hard about that. Looking around, some implementations are message based, some are stream based. There are good arguments for both. Unfortunately the WebSocket protocol is a messages based protocol with no maximum message length. A message is one or more frames and a frame is up to 2^63 bytes. While most usages will be small(ish) messages that can be buffered without undue overhead, any application that wants larger messages needs to use a stream based interface to be able to scale. That is why I went for both. Thanks for the feedback. Much appreciated. Mark - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
On 29 January 2012 10:19, Mark Thomas ma...@apache.org wrote: On 29/01/2012 01:20, Costin Manolache wrote: On Fri, Jan 27, 2012 at 3:09 PM, Mark Thomas ma...@apache.org wrote: Not complaining - it's great to add this feature, please commit it - but I'm wondering if a lighter interface wouldn't be better. From looking at the implementation, it seems after the upgrade it keeps the InputBuffer/OutputBuffer ( and the whole Request / Processor / etc tree ). I agree there is certainly scope to do that. My initial focus has been on functionality and minimal changes to existing code - hence the current approach. I'm not overly keen on the additional overhead myself and can see several ways to reduce it. Output is easier than input since we know the output buffers are clear on upgrade. Input is a little trickier since there may be some data in the input buffer and that would need to be drained before switching to the lighter weight approach. I think this is something to look at once the implementation is more feature complete. Whatever we do, I'd like to keep the following aims in mind: - minimal endpoint specific code - minimal changes to what we have now - keep the generic upgrade and the protocol specific parts separate Would it be possible for example to release the Request, like it's done after request, in keep-alive, and use a lighter parser/callback on the socket ? I think one of the use cases for websockets is to support a _lot_ of open connections. That is certainly one approach. It will be easier to explore options when we have a wider range of examples to work / test with. Also the interface may be simpler without InputStreams. I thought long and hard about that. Looking around, some implementations are message based, some are stream based. There are good arguments for both. Unfortunately the WebSocket protocol is a messages based protocol with no maximum message length. A message is one or more frames and a frame is up to 2^63 bytes. While most usages will be small(ish) messages that can be buffered without undue overhead, any application that wants larger messages needs to use a stream based interface to be able to scale. That is why I went for both. May I suggest that such design decisions are documented in the code and/or package Javadoc? Thanks for the feedback. Much appreciated. Mark - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
On Sun, Jan 29, 2012 at 2:19 AM, Mark Thomas ma...@apache.org wrote: On 29/01/2012 01:20, Costin Manolache wrote: On Fri, Jan 27, 2012 at 3:09 PM, Mark Thomas ma...@apache.org wrote: Not complaining - it's great to add this feature, please commit it - but I'm wondering if a lighter interface wouldn't be better. From looking at the implementation, it seems after the upgrade it keeps the InputBuffer/OutputBuffer ( and the whole Request / Processor / etc tree ). I agree there is certainly scope to do that. My initial focus has been on functionality and minimal changes to existing code - hence the current approach. I'm not overly keen on the additional overhead myself and can see several ways to reduce it. Output is easier than input since we know the output buffers are clear on upgrade. Input is a little trickier since there may be some data in the input buffer and that would need to be drained before switching to the lighter weight approach. I don't think the upgrade protocol allows clients to send payload before receiving the response headers / handshaking, so I think it wouldn't be a problem. In terms of actual code changes - I think the main problem is that nio/apr/oio input/output are implemented in Internal[Input/Output][Nio/Apr]Buffer which are quite heavy- it would be a huge change to modify that. However it may be possible to have some lighter buffers - just the socket and methods to read/write. At least that's what I've been trying with spdy - which also involves some protocol switching. The change is also minimal in endpoint-specific code ( it's just adding few hooks and some new code ). I think this is something to look at once the implementation is more feature complete. Whatever we do, I'd like to keep the following aims in mind: - minimal endpoint specific code - minimal changes to what we have now - keep the generic upgrade and the protocol specific parts separate I agree. Would it be possible for example to release the Request, like it's done after request, in keep-alive, and use a lighter parser/callback on the socket ? I think one of the use cases for websockets is to support a _lot_ of open connections. That is certainly one approach. It will be easier to explore options when we have a wider range of examples to work / test with. Also the interface may be simpler without InputStreams. I thought long and hard about that. Looking around, some implementations are message based, some are stream based. There are good arguments for both. Unfortunately the WebSocket protocol is a messages based protocol with no maximum message length. A message is one or more frames and a frame is up to 2^63 bytes. While most usages will be small(ish) messages that can be buffered without undue overhead, any application that wants larger messages needs to use a stream based interface to be able to scale. That is why I went for both. Well, the message is sent from javascript - I don't think 2^63 frames are likely, and even if they are, I don't think a blocking InputStream interface is best choice. Why not copy some of the javascript interface ( onopen / onmessage / etc ) ? Or onMessage(byte[] initialData) + onMessageData(byte[] moreBytes) ? In other words - make it 'async' from start. I wouldn't even worry about the string conversions for text frames in a low-level interface. Costin Thanks for the feedback. Much appreciated. Mark - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
On 29/01/2012 22:49, Costin Manolache wrote: On Sun, Jan 29, 2012 at 2:19 AM, Mark Thomas ma...@apache.org wrote: On 29/01/2012 01:20, Costin Manolache wrote: On Fri, Jan 27, 2012 at 3:09 PM, Mark Thomas ma...@apache.org wrote: Not complaining - it's great to add this feature, please commit it - but I'm wondering if a lighter interface wouldn't be better. From looking at the implementation, it seems after the upgrade it keeps the InputBuffer/OutputBuffer ( and the whole Request / Processor / etc tree ). I agree there is certainly scope to do that. My initial focus has been on functionality and minimal changes to existing code - hence the current approach. I'm not overly keen on the additional overhead myself and can see several ways to reduce it. Output is easier than input since we know the output buffers are clear on upgrade. Input is a little trickier since there may be some data in the input buffer and that would need to be drained before switching to the lighter weight approach. I don't think the upgrade protocol allows clients to send payload before receiving the response headers / handshaking, so I think it wouldn't be a problem. Good point. I thought I was seeing data arriving earlier than that but what you says makes sense. I'll need to go back and double check exactly what I was seeing. In terms of actual code changes - I think the main problem is that nio/apr/oio input/output are implemented in Internal[Input/Output][Nio/Apr]Buffer which are quite heavy- it would be a huge change to modify that. However it may be possible to have some lighter buffers - just the socket and methods to read/write. At least that's what I've been trying with spdy - which also involves some protocol switching. The change is also minimal in endpoint-specific code ( it's just adding few hooks and some new code ). Agree the lightweight buffers are the way to go. Also the interface may be simpler without InputStreams. I thought long and hard about that. Looking around, some implementations are message based, some are stream based. There are good arguments for both. Unfortunately the WebSocket protocol is a messages based protocol with no maximum message length. A message is one or more frames and a frame is up to 2^63 bytes. While most usages will be small(ish) messages that can be buffered without undue overhead, any application that wants larger messages needs to use a stream based interface to be able to scale. That is why I went for both. Well, the message is sent from javascript - I don't think 2^63 frames are likely, and even if they are, I don't think a blocking InputStream interface is best choice. Blocking was simpler to implement. As I think I said earlier in this thread, non-blocking is a possible enhancement - if there is interest - but it isn't my focus right now. Also at the back of my mind is a preference that this works with BIO as it isn't clear to me at this point what the Servlet spec is going to end up saying about web socket support and I'd rather not end up in the position where using BIO meant non-spec compliance. There are a lot of unknowns there so this may end up being an unnecessary restriction. Overall, it is early days for WebSocket so I may end up being completely wrong about a lot of this. We'll see how things evolve. Why not copy some of the javascript interface ( onopen / onmessage / etc ) ? The interface isn't complete yet. What you describe is not a million miles from what I expect the Message based interface will end up looking like. That said, it appears from reading the protocol and various blogs around it that the folks that wrote it had all sorts of weird and wonderful clients in mind for this and that has certainly influenced the protocol design. If all clients were JavaScript the protocol would look very different (and the server side would be a whole lot easier to implement). I am trying to keep the options open rather than impose arbitrary limits on things to make a particular interface viable. Or onMessage(byte[] initialData) + onMessageData(byte[] moreBytes) ? In other words - make it 'async' from start. I wouldn't even worry about the string conversions for text frames in a low-level interface. What I have so far is also influenced by what other containers are doing with a view to getting some form of convergence. I think all the containers are taking the view that their current API is a starting point and things are likely to change a lot. How they change will (hopefully) be driven by user demand. We'll see where we end up. Cheers, Mark - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
On Fri, Jan 27, 2012 at 3:09 PM, Mark Thomas ma...@apache.org wrote: On 26/01/2012 23:15, Mark Thomas wrote: Good news. The WebSocket implementation has reached a state where you should be able to play with it. Receiving and sending of binary and text data via streams/writers and messages is all working as long as you don't use continuation frames. See the Echo example for the general idea. Some minor tweaks and clean-up [1]. Main improvement is that now if you write more data than the buffer can handle it doesn't fall over. I'm leaning towards committing this on the grounds that it changes very little of the existing code and - fingers crossed - it should stay that way. It will be easier for the wider community to experiment and provide patches once it is in trunk. I expect that the back-port to 7.0.x will wait until things were more feature complete and any obvious performance issues had been addressed. No-one has complained about this (yet) so I'll probably commit this some time next week. Not complaining - it's great to add this feature, please commit it - but I'm wondering if a lighter interface wouldn't be better. From looking at the implementation, it seems after the upgrade it keeps the InputBuffer/OutputBuffer ( and the whole Request / Processor / etc tree ). Would it be possible for example to release the Request, like it's done after request, in keep-alive, and use a lighter parser/callback on the socket ? I think one of the use cases for websockets is to support a _lot_ of open connections. Also the interface may be simpler without InputStreams. Costin Anyway, I hope you enjoy playing with this. As always, feedback welcome. Mark [1] http://people.apache.org/~markt/patches/draft/2012-01-27-websocket.patch - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
On 26/01/2012 23:15, Mark Thomas wrote: Good news. The WebSocket implementation has reached a state where you should be able to play with it. Receiving and sending of binary and text data via streams/writers and messages is all working as long as you don't use continuation frames. See the Echo example for the general idea. Some minor tweaks and clean-up [1]. Main improvement is that now if you write more data than the buffer can handle it doesn't fall over. I'm leaning towards committing this on the grounds that it changes very little of the existing code and - fingers crossed - it should stay that way. It will be easier for the wider community to experiment and provide patches once it is in trunk. I expect that the back-port to 7.0.x will wait until things were more feature complete and any obvious performance issues had been addressed. No-one has complained about this (yet) so I'll probably commit this some time next week. Anyway, I hope you enjoy playing with this. As always, feedback welcome. Mark [1] http://people.apache.org/~markt/patches/draft/2012-01-27-websocket.patch - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
On 25/01/2012 13:17, jean-frederic clere wrote: On 01/25/2012 02:00 PM, Mark Thomas wrote: On 25/01/2012 08:11, Mladen Turk wrote: On 01/24/2012 10:15 PM, Mark Thomas wrote: I have made some further headway with this and the latest patch is on people.a.o [1]. How that relates to Servlet spec 3.1? TBD :) Even if it would not make it into servlet 3.1 it is a _very_ feature to have. Good news. The WebSocket implementation has reached a state where you should be able to play with it. Receiving and sending of binary and text data via streams/writers and messages is all working as long as you don't use continuation frames. See the Echo example for the general idea. Control messages are not supported at all (so you can't close the connection yet). You'll need to apply [1] to trunk. I'm leaning towards committing this on the grounds that it changes very little of the existing code and - fingers crossed - it should stay that way. It will be easier for the wider community to experiment and provide patches once it is in trunk. I expect that the back-port to 7.0.x will wait until things were more feature complete and any obvious performance issues had been addressed. There are features still to be implemented and I know there is plenty of scope to improve performance. One example is that the reading and writing of data passes through rather more layers than it needs to. I'd like to explore adding rawRead() and rawWrite() to the InputBuffer and OutputBuffer which would access the socket directly. Another area is GC. I have paid little attention to GC concerns while writing this. I dread to think how much heap this will chew up under load. I haven't approached the Jetty folks regarding aligning to a common interface just yet. I want to let things bed down a little more first. Anyway, I hope you enjoy playing with this. As always, feedback welcome. Mark [1] http://people.apache.org/~markt/patches/draft/2012-01-26-websocket.patch - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
On 01/24/2012 10:15 PM, Mark Thomas wrote: I have made some further headway with this and the latest patch is on people.a.o [1]. How that relates to Servlet spec 3.1? Regards -- ^TM - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
On 25/01/2012 08:11, Mladen Turk wrote: On 01/24/2012 10:15 PM, Mark Thomas wrote: I have made some further headway with this and the latest patch is on people.a.o [1]. How that relates to Servlet spec 3.1? TBD :) Current thinking is that servlet 3.1 will provide some hooks to start and upgrade process but that protocol implementation will be left to the container (rather than providing an API that applications could code to to implement the new protocol). As it happens, I think we have in Tomcat something that could be turned into a generic upgrade API that applications could code to but we need to see how that turns out performance-wise. You'll notice that all the integration points are protocol neutral so we (or anyone else) could easily extend this to support other protocols. The relevant part of the code is in the WebSocketServlet: // Small hack until the Servlet API provides a way to do this. StreamListener listener = createWebSocketConnection(); UpgradeConnection uc = ((RequestFacade) req).doUpgrade(listener); StreamConnection sc = new StreamConnection(uc); listener.setConnection(sc); I'm expecting some form of doUpgrade() method to be added to the HttpServletRequest class but exactly what form that will take is TBD. I believe the plan is to wait until the WebSocket JSR is further along and react to their requirements. Hopefully, the experience of Tomcat, Jetty and others implementing WebSocket will feed into that. Mark - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
On 01/25/2012 02:00 PM, Mark Thomas wrote: On 25/01/2012 08:11, Mladen Turk wrote: On 01/24/2012 10:15 PM, Mark Thomas wrote: I have made some further headway with this and the latest patch is on people.a.o [1]. How that relates to Servlet spec 3.1? TBD :) Even if it would not make it into servlet 3.1 it is a _very_ feature to have. Cheers Jean-Frederic - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: WebSocket progress report
On 24.01.2012 22:15, Mark Thomas wrote: I have made some further headway with this and the latest patch is on people.a.o [1]. Looks nice, especially I like that the integration into the existing code base isn't very complex. Good work! Thanks also for all the additional explanations. Rainer - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org