This is great, Fraser! You're certainly an enterprising fellow, eh? :-) I chair the OASIS AMQP Bindings and Mappings Technical Committee and one of the things that TC is doing is developing a spec for AMQP over Websockets. The Websockets binding is getting near to a public review committee specification, and it would be great to have your input, and maybe participate in a little interop work. If you/your employer are an OASIS member, your input on the TC would be very welcome now, before the spec goes for public review.
Thanks, -Steve > -----Original Message----- > From: Fraser Adams [mailto:fraser.ad...@blueyonder.co.uk] > Sent: Tuesday, November 19, 2013 2:56 PM > To: users@qpid.apache.org > Subject: Proof of Concept JavaScript Proton implementation. > > Hey all, > For the last couple of weekends I've been working on a Proof of Concept > JavaScript implementation of Proton. > > The approach that I've taken is (I think) quite interesting/unusual but it's > an > approach that offers a high level of synergy with implementations for other > languages that are essentially bindings to proton-c. > > The "magic elixir" in this is the downright amazing emscripten > https://github.com/kripken/emscripten/wiki which (believe it or not) is > essentially a cross-compiler that can compile C/C++ to JavaScript. > Moreover the JavaScript that it compiles to is a particular subset called > asm.js > http://asmjs.org/ which can be extremely aggressively optimised and is > subject to a lot of research by Mozilla in particular (the main emscripten > maintainer is actually a Mozilla researcher, though I believe emscripten is > something of a side project). > > It's well worth visiting the emscripten page with a modern browser, the Epic > Citadel demo is awesome :-) > > So in a nutshell what I've done is to compile proton-c into JavaScript > > So I'm underselling it a bit :-) I had to do a fair bit of work to make it > that > simple, in particular I had to add/fix a number of emscripten's library > functions (Proton used a few things that weren't implemented) but the cool > thing is that those are now in emscripten for everyone's benefit. > > A really nice thing is that I've not actually had to modify any of the > engine/messenger code at all - one I started to figure out what I was doing > wrong that is :-) all I've really needed to to was to modify send.c/recv.c so > that they behave in a non-blocking manner (you may have seen my mail at > the weekend before I finally figured it out :-)) > > I've got CMake able to cross-compile in a repeatable fashion so the only > change to any existing Proton stuff that is required is an addition to the > top- > level CMakeLists.txt that detects the presence of emscripten and its > dependencies and if present fires off > "add_subdirectory(bindings/javascript)" e.g. > > > # Build the JavaScript language binding. > # This is somewhat different to the other language bindings in that it does > not use swig. It uses a C/C++ to # JavaScript cross-compiler called emscripten > (https://github.com/kripken/emscripten). Emscripten takes C/C++ # and > "compiles" it into a highly optimisable subset of JavaScript called asm.js > (http://asmjs.org/) that can # be aggressively optimised and run at near- > native speed (usually between 1.5 to 10 times slower than native C/C++). > option("BUILD_JAVASCRIPT" "Build JavaScript language binding" ON) if > (BUILD_JAVASCRIPT) > # First check that Node.js is installed as that is needed by emscripten. > find_program(NODE node) > if (NOT NODE) > message(STATUS "Node.js (http://nodejs.org) is not installed: can't build > JavaScript binding") > else (NOT NODE) > # Check that the emscripten C/C++ to JavaScript cross-compiler is > installed. > find_program(EMCC emcc) > if (NOT EMCC) > message(STATUS "Emscripten > (https://github.com/kripken/emscripten) is not installed: can't build > JavaScript binding") > else (NOT EMCC) > add_subdirectory(bindings/javascript) > endif (NOT EMCC) > endif (NOT NODE) > endif (BUILD_JAVASCRIPT) > > > So the main purpose of this mail is to give a heads up of it and to ask if > it'd be > OK to start commiting it and give others some visibility of it. > > At this stage it's something of a Proof of Concept, in particular: > * I haven't exported any actual JavaScript bindings so although it's > JavaScript > actual JavaScript clients would find it awkward to call the API as yet. > * As alluded above and at the weekend the demo code I've got calling > messenger isn't especially elegant, I think I know how to get things behaving > more asynchronously, but haven't tried it yet (and my hunch may be wrong). > * Transport is entirely over WebSockets :-) so I've actually got send and recv > running on Node.js (and also send on a browser) but it'd be useful to have > them communicate via TCP sockets too - though that'd need a proxy. > * I still (perhaps amusingly given this) don't know that much about Proton, so > I've only really got send and recv to play with I'm not really sure where > there > may be other messenger examples to exercise it a bit better (in particular > message type interoperability would be good to test). I'd be grateful for > pointers - is the object.c test the best place to look for this? And I > couldn't > see any tests for the "tracker" > capabilities?? > * In case it wasn't clear from the WebSockets it'll only work in a relatively > modern browser at the moment both for the WebSocket stuff and for the > fact that it relies on ArrayBuffers (though there's an emscripten compile > option to allow the use of native JavaScript Arrays > instead) > > > Finally it's probably worth pointing out some pros and cons for this approach > to creating a JavaScript Proton > Pro: > * It's using the existing proton-c code base with the posix driver.c > completely > unchanged (with the simple test I've done to date) so from a broad > maintenance/"Total cost of Ownership" perspective it means essentially very > little extra maintenance costs. > * It follows the same "pattern" as Python/Perl/PHP/Ruby/Java JNI albeit it's > cross-compiled rather than a pure binding. > * It should be somewhat faster than "handwritten" JavaScript. This might > seem counter-intuitive but it's worth looking at the emscripten/asm.js > documentation. From my own experience I've ported zlib to JavaScript for > another project I'm working on and inflate was *significantly* faster than the > literal port of tinflate that I had previously used - and that was on a > relatively > old Firefox without asm.js optimisations. > > Con: > * The compiled code is likely to be somewhat larger than hand written > JavaScript. I haven't done an optimised & minified build yet so I can't say > for > sure how big it will actually be. The unoptimised send.js/recv.js are 1.5MB > each so at a guess they'll probably come out at arounf the ~500K mark > (though they should also gzip quite well). > * The compiled code isn't necessarily hugely readable. It's "OK" when not > optimised but.... (to be fair I used it to figure out how to get the missing > library calls working so it's not *totally* impenetrable :-)) > > > I hope that this is something that'll be useful/interesting please do let me > know if you're all happy for me to get it kicked off into the Proton code > base. > > Best regards, > Frase > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: users-unsubscr...@qpid.apache.org For additional > commands, e-mail: users-h...@qpid.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@qpid.apache.org For additional commands, e-mail: users-h...@qpid.apache.org