You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by rh...@apache.org on 2014/11/28 14:50:14 UTC

[36/51] [abbrv] qpid-proton git commit: Add a mechanism to allow the emscripten virtual heap size to be specified at run-time by applications rather than having to change it at compile-time. Improve the documentation especially the main README

Add a mechanism to allow the emscripten virtual heap size to be specified at run-time by applications rather than having to change it at compile-time. Improve the documentation especially the main README

git-svn-id: https://svn.apache.org/repos/asf/qpid/proton/branches/fadams-javascript-binding@1626584 13f79535-47bb-0310-9956-ffa450edef68


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/2cf80a9e
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/2cf80a9e
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/2cf80a9e

Branch: refs/heads/master
Commit: 2cf80a9e7181f2929dea5aa2c6adc935af6262bc
Parents: 929eab4
Author: fadams <fa...@unknown>
Authored: Sun Sep 21 14:44:57 2014 +0000
Committer: fadams <fa...@unknown>
Committed: Sun Sep 21 14:44:57 2014 +0000

----------------------------------------------------------------------
 examples/messenger/javascript/send.html       |  14 +-
 examples/messenger/javascript/send.js         |   3 +-
 proton-c/bindings/javascript/README           | 381 ++++++++++++++++++++-
 proton-c/bindings/javascript/TODO             |  48 ++-
 proton-c/bindings/javascript/binding-close.js |  12 +-
 proton-c/bindings/javascript/module.js        |  51 ++-
 6 files changed, 471 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2cf80a9e/examples/messenger/javascript/send.html
----------------------------------------------------------------------
diff --git a/examples/messenger/javascript/send.html b/examples/messenger/javascript/send.html
index 382b293..dc8b448 100644
--- a/examples/messenger/javascript/send.html
+++ b/examples/messenger/javascript/send.html
@@ -26,18 +26,24 @@
 	<meta http-equiv="content-type" content="text/html;charset=utf-8" />
 
 <!--
-  Import JavaScript Messenger Binding proton.js. Note that this simple example pulls
-  it from the node_modules/qpid-proton/lib which is created by the build process
+  Import the Messenger Binding proton.js. Note that this simple example pulls
+  it from the node_modules/qpid-proton/lib, which is created by the build process
   so that the node.js based examples "just work", in a real Web App you would need
-  to copy the proton.js to your own server. 
+  to copy the proton.js to your own server.
+
   In actual fact the CMake build actually builds proton.js into the directory:
   <build>/proton-c/bindings/javascript
   where <build> is the build directory created to run cmake from.
+
+  In this example we also set the global variable PROTON_HEAP_SIZE in order to
+  increase the virtual heap available to the emscripten compiled C runtime. It
+  is not really necessary to do this for this application as the default value
+  of 16777216 is fine, it is simply done here to illustrate how to do it.
 -->
+<script type="text/javascript">PROTON_HEAP_SIZE = 50000000;</script>
 <script type="text/javascript" src="../../../node_modules/qpid-proton/lib/proton.js"></script>
 
 <script type="text/javascript">
-
 var message = new proton.Message();
 var messenger = new proton.Messenger();
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2cf80a9e/examples/messenger/javascript/send.js
----------------------------------------------------------------------
diff --git a/examples/messenger/javascript/send.js b/examples/messenger/javascript/send.js
index 9c48fab..0ca3a7e 100644
--- a/examples/messenger/javascript/send.js
+++ b/examples/messenger/javascript/send.js
@@ -20,11 +20,12 @@
  */
 
 // Check if the environment is Node.js and if not log an error and exit.
-if (!exports) {
+if (typeof process !== 'object' || typeof require !== 'function') {
     console.error("send.js should be run in Node.js");
     return;
 }
 
+PROTON_HEAP_SIZE = 50000000;
 var proton = require("qpid-proton");
 
 var address = "amqp://0.0.0.0";

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2cf80a9e/proton-c/bindings/javascript/README
----------------------------------------------------------------------
diff --git a/proton-c/bindings/javascript/README b/proton-c/bindings/javascript/README
index 1998a47..a29352d 100644
--- a/proton-c/bindings/javascript/README
+++ b/proton-c/bindings/javascript/README
@@ -4,6 +4,115 @@ Qpid Proton JavaScript Language Bindings
 The code contained herein provides JavaScript language bindings for working
 with the Qpid Proton AMQP 1.0 protocol engine and messenger library.
 
+Important Note - Modern Browser Needed
+======================================
+
+The JavaScript binding requires ArrayBuffer/TypeArray and WebSocket support.
+Both of these are available in most "modern" browser versions. The author has
+only tried running on FireFox and Chrome, though recent Safari, Opera and IE10+
+*should* work too - YMMV. It might be possible to polyfill for older browsers
+but the author hasn't tried this.
+
+Important Note - WebSocket Transport!!!
+=======================================
+
+Before going any further it is really important to realise that the JavaScript
+bindings to Proton are somewhat different to the bindings for other languages
+because of the restrictions of the execution environment. In particular it is
+very important to note that the JavaScript bindings by default use a WebSocket
+transport and not a TCP transport, so whilst it's possible to create Server style
+applications that clients can connect to (e.g. recv.js and send.js) it is very
+important to note that:
+
+JavaScript clients cannot *directly* talk to "normal" AMQP applications such as
+qpidd or the Java Broker because they use the traditional TCP transport.
+
+This is a slightly irksome issue, but there's no getting away from it because
+it's a security restriction imposed by the browser environment.
+
+
+At the moment even for Node.js we are limited to using a WebSocket transport, but
+it is on the author's "TODO" list to look at providing a means to use either a
+WebSocket transport or a native TCP transport (via node's net library). It should
+also be possible to use native TCP for Chrome "packaged apps", but again this is
+only on the TODO list so if you want to talk to a "normal" AMQP application you
+must live with the WebSocket constraints.
+
+Option 1. proxy from WebSockets to TCP sockets
+<proton>/examples/messenger/javascript/proxy.js
+is a simple Node.js WebSocket<->TCP Socket proxy, simple doing:
+
+node proxy.js
+
+will stand up a proxy listening by default on WebSocket port 5673 and forwarding
+to TCP port 5672 (this is configurable for options do: node proxy.js -h)
+
+Rather than using a stand-alone proxy it is possible to have applications stand
+up their own proxy (where lport = listen port, thost = target host and
+tport = target port):
+
+var proxy = require('./ws2tcp.js');
+proxy.ws2tcp(lport, thost, tport);
+
+For talking to the C++ broker unfortunately proxying is currently the only option
+as qpidd does not have a WebSocket transport.
+
+Option 2. The Java Broker's WebSocket transport.
+Recent releases of the Qpid Java Broker provide a native WebSocket transport which
+means that the JavaScript binding can talk to it with no additional requirements.
+It is necessary to configure the Java Broker as the WebSocket transport is not
+enabled by default. In <qpid-work>/config.json in the "ports" array you need to add:
+
+{
+    "authenticationProvider" : "passwordFile",
+    "name" : "AMQP-WS",
+    "port" : "5673",
+    "transports" : [ "WS" ]
+}
+
+This sets the JavaBroker to listen on WebSocket port 5673 similar to the proxy.
+
+
+One gotcha that still bites the author *** DO NOT FORGET *** that you will be
+using ports that you are not used to!! If you are not connecting check that the
+proxy is running and that you are specifying the right ports. I still mess up :-(
+
+WebRTC Transport
+================
+
+A WebRTC Transport is supported by emscripten, though the author has not tried it.
+If you wan to play with this you are very much on your own at the moment YMMV.
+
+This is configured by adding to the LINK_FLAGS in CMakeLists.txt
+-s \"SOCKET_WEBRTC=1\"
+
+  /* WebRTC sockets supports several options on the Module object.
+
+     * Module['host']: true if this peer is hosting, false otherwise
+     * Module['webrtc']['broker']: hostname for the p2p broker that this peer should use
+     * Module['webrtc']['session']: p2p session for that this peer will join, or undefined if this peer is hosting
+     * Module['webrtc']['hostOptions']: options to pass into p2p library if this peer is hosting
+     * Module['webrtc']['onpeer']: function(peer, route), invoked when this peer is ready to connect
+     * Module['webrtc']['onconnect']: function(peer), invoked when a new peer connection is ready
+     * Module['webrtc']['ondisconnect']: function(peer), invoked when an existing connection is closed
+     * Module['webrtc']['onerror']: function(error), invoked when an error occurs
+   */
+
+If you wanted to play with these you'd likely have to tweak the module.js code in
+<proton>/proton-c/bindings/javascript
+
+The emscripten documentation is a bit light on the WebRTC Transport too, though
+
+emscripten/tests/test_sockets.py
+emscripten/tests/sockets/webrtc_host.c
+emscripten/tests/sockets/webrtc_peer.c
+emscripten/tests/sockets/p2p/broker/p2p-broker.js
+emscripten/tests/sockets/p2p/client/p2p-client.js
+
+Look like they provide a starting point.
+Very much TODO......
+
+
 Creating The Bindings
 =====================
 
@@ -11,26 +120,35 @@ To generate the JavaScript bindings we actually cross-compile from proton-c
 
 You will need to have emscripten (https://github.com/kripken/emscripten) installed
 to do the cross-compilation and in addition you will require a few things that
-emscripten itself depends upon. https://github.com/kripken/emscripten/wiki/Emscripten-SDK
+emscripten itself depends upon.
+
+http://kripken.github.io/emscripten-site/docs/building_from_source/index.html#installing-from-source
+http://kripken.github.io/emscripten-site/docs/building_from_source/toolchain_what_is_needed.html
+provides instructions for installing emscripten and the "fastcomp" LLVM backend.
+This approach lets users use the "bleeding edge" version of emscripten on the
+"incoming" branch (pretty much analogous to building qpid/proton off svn trunk).
+This is the approach that the author of the JavaScript Bindings tends to use.
+
+
+http://kripken.github.io/emscripten-site/docs/getting_started/downloads.html
 provides some fairly easy to follow instructions for getting started on several
 platforms the main dependencies are as follows (on Windows the SDK includes these):
 
-* The Emscripten code, from github (git clone git://github.com/kripken/emscripten.git.
-  The documentation suggests master branch but in the short term incoming is
-  probably better as a few updates to emscripten have been added to help get
-  proton working and these may take a little while to get merged back to master.
+* The Emscripten code, from github (git clone git://github.com/kripken/emscripten.git).
 * LLVM with Clang. Emscripten uses LLVM and Clang, but at the moment the JavaScript
   back-end for LLVM is off on a branch so you can't use a stock LLVM/Clang.
-  https://github.com/kripken/emscripten/wiki/LLVM-Backend has lots of explanation
-  and some easy to follow instructions for downloading and building fast-comp
+  http://kripken.github.io/emscripten-site/docs/building_from_source/LLVM-Backend.html
+  http://kripken.github.io/emscripten-site/docs/building_from_source/building_fastcomp_manually_from_source.html#building-fastcomp-from-source
+  has lots of explanation and some easy to follow instructions for downloading
+  and building fastcomp
 * Node.js (0.8 or above; 0.10.17 or above to run websocket-using servers in node)
 * Python 2.7.3
 * Java is required in order to use the Closure Compiler to minify the code.
   
 
 If you haven't run Emscripten before it's a good idea to have a play with the
-tutorial https://github.com/kripken/emscripten/wiki/Tutorial
-
+tutorial here:
+http://kripken.github.io/emscripten-site/docs/getting_started/Tutorial.html
 
 
 
@@ -44,7 +162,8 @@ the root directory) it's:
   cmake ..
   make
 
-and you should be all set, to test it's all working do:
+and you should be all set, to test it's all working do (from the build directory):
+  cd proton-c/bindings/javascript/examples
 
   node recv-async.js
 
@@ -52,14 +171,243 @@ in one window and
 
   node send-async.js
 
-in another
+in another.
+
+These examples are actually JavaScript applications that have been directly
+compiled from recv-async.c and send-async.c in <proton>/examples/messenger/c
+if you'd prefer to write applications in C and compile them to JavaScript that
+is a perfectly valid approach and these examples provide a reasonable starting
+point for doing so.
+
+Documentation
+=============
+
+When you've successfully got a successful build do:
+
+  make docs
+
+Which will make all of the proton documentation including the JavaScript docs.
+If successful the JSDoc generated documentation should be found here:
+
+<proton>/build/proton-c/bindings/javascript/html/index.html
+
+
+Using "native" JavaScript
+=========================
+
+The examples in <proton>/examples/messenger/javascript are the best starting point.
+
+In practice the examples follow a fairly similar pattern to the Python bindings
+the most important thing to bear in mind though is that JavaScript is completely
+asynchronous/non-blocking, which can catch the unwary.
+
+An application follows the following (rough) steps:
+
+1. (optional) Set the heap size.
+It's important to realise that most of the library code is compiled C code and
+the runtime uses a "virtual heap" to support the underlying malloc/free. This is
+implemented internally as an ArrayBuffer with a default size of 16777216.
+
+To allocate a larger heap an application must set the PROTON_HEAP_SIZE global.
+In Node.js this would look like (see send.js):
+PROTON_HEAP_SIZE = 50000000; // Note no var - it needs to be global.
+
+In a browser it would look like (see send.html):
+<script type="text/javascript">PROTON_HEAP_SIZE = 50000000;</script>
+
+2. Load the library and create a message and messenger.
+In Node.js this would look like (see send.js):
+var proton = require("qpid-proton");
+var message = new proton.Message();
+var messenger = new proton.Messenger();
 
+In a browser it would look like (see send.html):
+<script type="text/javascript" src="../../../node_modules/qpid-proton/lib/proton.js"></script>
 
-KNOWN ISSUES
-============
+<script type="text/javascript">
+var message = new proton.Message();
+var messenger = new proton.Messenger();
+....
 
-send-async and recv-async are both pretty hacky at the moment.
+3. Set up event handlers as necessary.
 
+messenger.on('error', <error callback>);
+messenger.on('work', <work callback>);
+messenger.on('subscription', <subscription callback>);
+
+The work callback is triggered on WebSocket events, so in general you would use
+this to send and receive messages, for example in recv.js we have:
+
+var pumpData = function() {
+    while (messenger.incoming()) {
+        var t = messenger.get(message);
+
+        console.log("Address: " + message.getAddress());
+        console.log("Subject: " + message.getSubject());
+
+        // body is the body as a native JavaScript Object, useful for most real cases.
+        //console.log("Content: " + message.body);
+
+        // data is the body as a proton.Data Object, used in this case because
+        // format() returns exactly the same representation as recv.c
+        console.log("Content: " + message.data.format());
+
+        messenger.accept(t);
+    }
+};
+
+messenger.on('work', pumpData);
+
+
+The subscription callback is triggered when the address provided in a call to
+messenger.subscribe(<address>);
+
+Gets resolved. An example of its usage can be found in qpid-config.js which is
+a fully functioning and complete port of the python qpid-config tool. It also
+illustrates how to do asynchronous request/response based applications.
+
+Aside from the asynchronous aspects the rest of the API is essentially the same
+as the Python binding aside from minor things such as camel casing method names etc.
+
+Serialisation/Deserialisation, Types etc.
+=========================================
+
+The JavaScript binding tries to be as simple, intuitive and natural as possible
+so when sending a message all native JavaScript types including Object literals
+and Arrays are transparently supported, for example.
+
+var message = new proton.Message();
+message.setAddress('amqp://localhost');
+message.setSubject('UK.NEWS');
+message.body = ['Rod', 'Jane', 'Freddy', {cat: true, donkey: 'hee haw'}];
+
+
+The main things to bear in mind is that (particularly for sending messages) we
+may need to use "adapters" to make sure values are correctly interpreted and
+encoded to the correct type in the AMQP type system. This is especially important
+when interoperating with a peer written in a strongly typed language (C/C++/Java).
+
+Some examples of available types follow:
+
+// UUID
+message.body = new proton.Data.Uuid();
+
+// AMQP Symbol
+message.body = new proton.Data.Symbol("My Symbol");
+
+// Binary data (created from a String in this case).
+message.body = new proton.Data.Binary("Monkey Bathпогромзхцвбнм");
+
+// Binary data (Get a Uint8Array view of the data and directly access that).
+message.body = new proton.Data.Binary(4);
+var buffer = message.body.getBuffer();
+buffer[0] = 65;
+buffer[1] = 77;
+buffer[2] = 81;
+buffer[3] = 80;
+
+// Binary Data (Created from an Array, you can use an ArrayBuffer/TypedArray too).
+message.body = new proton.Data.Binary([65, 77, 81, 80]);
+
+
+Note that the implementation of proton.Data.Binary tries to minimise copying so
+it accesses the internal emscripten heap *directly* this requires memory management
+which is mostly handled transparently, but users need to be aware that the
+underlying memory is "owned" by the Message Object so if Binary data needs to
+be maintained after the next call to messenger.get(message); it must be
+*explicitly* copied. For more detail do "make docs" and see:
+<proton>/build/proton-c/bindings/javascript/html/proton.Data.Binary.html
+
+
+// AMQP Described (value, descriptor)
+message.body = new proton.Data.Described('persian, 'com.cheezburger.icanhas');
+
+// AMQP Timestamp maps to native JavaScript Date.
+message.body = new Date();
+
+// Various AMQP Array examples.
+message.body = new proton.Data.Array('INT', [1, 3, 5, 7], "odd numbers");
+message.body = new proton.Data.Array('UINT', [1, 3, 5, 7], "odd");
+message.body = new proton.Data.Array('ULONG', [1, 3, 5, 7], "odd");
+message.body = new proton.Data.Array('FLOAT', [1, 3, 5, 7], "odd");
+message.body = new proton.Data.Array('STRING', ["1", "3", "5", "7"], "odd");
+
+// A JavaScript TypedArray will map directly to and from an AMQP Array of the
+// appropriate type (Internally sets a descriptor of 'TypedArray').
+message.body = new Uint8Array([1, 3, 5, 7]);
+
+// UUID Array
+message.body = new proton.Data.Array('UUID', [new proton.Data.Uuid(), new proton.Data.Uuid(), new proton.Data.Uuid(), new proton.Data.Uuid()], "unique");
+
+// Null
+message.body = null;
+
+// Boolean
+message.body = true;
+
+// Native JavaScript Array maps to an AMQP List
+message.body = ['Rod', 'Jane', 'Freddy'];
+
+// Native JavaScript Object maps to an AMQP Map
+message.body = ['Rod', 'Jane', 'Freddy', {cat: true, donkey: 'hee haw'}];
+
+// JavaScript only has a "number" type so the binding provides "decorator"
+// methods added to the JavaScript Number class. To access this from number
+// primitives it is necessary to either use braces or use a "double dot" so that
+// the interpreter can disambiguate from a simple decimal point. The binding will
+// attempt to use the correct type such that message.body = 2147483647; would be
+// sent as an AMQP integer but because of the way JavaScript coerces integers
+// message.body = 2147483647.0; would also be sent as an AMQP integer because
+// 2147483647.0 gets transparently conveted to 2147483647 by the interpreter so
+// to explicitly send this as an AMQP float we'd need to do:
+// message.body = 2147483647.0.float();
+
+// Some more number examples:
+message.body = 66..char();  // char
+message.body = 2147483647;  // int
+message.body = -2147483649; // long
+message.body = 12147483649; // long
+message.body = (12147483649).long(); // long
+message.body = (17223372036854778000).ulong(); // ulong
+message.body = (121474.836490).float(); // float
+message.body = 12147483649.0.float(); // float
+message.body = (4294967296).uint(); // uint
+message.body = (255).ubyte(); // ubyte
+
+Note too that floats are subject to a loss of precision
+
+
+Fortunately most of these quirks only affect serialisation.when the binding
+receives a message it will attempt to decode it into the most "natural" native
+JavaScript type.
+
+
+One additional decoding "quirk" can be caused by C++ qpid::messaging clients. It
+is unfortunately quite common for C++ clients to incorrectly encode Strings as
+AMQP Binary by neglecting to provide an encoding. The QMF Management Agent is one
+such culprit. This is a bit of a pain, especially because of proton.Data.Binary
+memory management quirks and having to remember to explicitly copy the data
+on each call to messenger.get(message); In order to cater for this an overloaded
+messenger.get(message, true); has been provided. Setting the second parameter to
+true forces any received Binary payloads to be decoded as Strings. If you know
+that producers might behave in this way and you are not expecting any "real"
+Binary data from the producer this convenience mechanism results in nice clean
+JavaScript Objects being received and is extremely useful for things like QMF.
+
+JSON
+====
+
+As well as allowing native JavaScript Objects and Arrays to be transparently
+serialised and deserialised via the AMQP type system it is also possible to
+serialise/deserialise as JSON.
+
+message.setAddress('amqp://localhost');
+message.setContentType('application/json');
+message.body = {array: [1, 2, 3, 4], object: {name: "John Smith", age: 65}};
+
+On the wire the above will be encoded as an opaque binary in an AMQP data section
+but will be deserialised into a JavaScript Object in exactly the same was as the
+previous examples that use the AMQP type system.
 
 SUPPORT
 =======
@@ -69,5 +417,10 @@ a tracker request:
 
     https://issues.apache.org/jira/browse/PROTON
 
+The main support channel is the qpid-users mailing list, see:
+
+    http://qpid.apache.org/discussion.html#mailing-lists
+
 You can also directly interact with the development team and other users
 in the #qpid channel on irc.freenode.net.
+

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2cf80a9e/proton-c/bindings/javascript/TODO
----------------------------------------------------------------------
diff --git a/proton-c/bindings/javascript/TODO b/proton-c/bindings/javascript/TODO
index bd1d158..092ee2e 100644
--- a/proton-c/bindings/javascript/TODO
+++ b/proton-c/bindings/javascript/TODO
@@ -1,11 +1,49 @@
 Qpid Proton JavaScript Language Bindings TODO List
 ==================================================
 
-The code base contains some tweaked emscripten library code, this is ultimately going
-to get done properly, commited back to emscripten and removed from here.
+Network code is currently limited to a WebSocket transport, including for Node.js
+It would be good to allow a configurable transport so that Node.js and Chrome
+packaged apps could use native TCP sockets.
 
+The JavaScript binding is pure JavaScript, that has been  trans-compiled from C
+to JavaScript using emscripten. This allows the same code to be used in a browser
+and Node.js, but it potentially has a performance penalty in Node.js. An alternative
+for Node.js might be to build a SWIG binding (recent versions of SWIG support
+JavaScript). This should be viewed as a complementary not competing approach as
+it would only work for environments like Node.js and definitely *not* browser
+environments which clearly require pure JavaScript.
+
+Optimisation are enabled for compiling and linking but there hasn't been any
+profiling done yet. The binding code *shouldn't* be the bottleneck but it's
+always possible that I messed up.
+
+Error handling is nowhere near as good as it should be, though this is mostly
+because Messenger itself is a bit lacking on the error handling/recovery front.
+
+Although described as "Proton" this is currently a JavaScript binding for Messenger
+and associated Message & Data classes. There has been some talk on the user list
+of an alternative reactive API based on proton Engine. This might ultimately be
+a better fit for JavaScript but it is very much in its infancy and I haven't
+really looked at it yet.
+
+proton-j seems to use hawt-dispatch, which is modelled after Grand Central
+Dispatch so I need to work out what it's using it do do and whether there are
+parallels in proton-c
+
+Although the WebSocket transport uses the sub-protocol 'AMQPWSB10' as specified
+in http://docs.oasis-open.org/amqp-bindmap/amqp-wsb/v1.0/amqp-wsb-v1.0.html
+section 2.1 is is not technically compliant with the spec. as the AMQP data is
+created by the proton-c code, which produces a data-stream for the TCP transport
+whereas the WebSocket spec. seems to want to make use of the fact that WebSocket
+is a frame based transport (whereas TCP is not). This is quite hard to resolve
+as the binding simply sends the contents of the octet buffer created by proton
+over the transport and thus to make this binding compliant with the spec. would
+require a change to the underlying proton-c code! It is possible that this may be
+done in future as any SCTP would require the ability to push AMQP frames too.
+In the mean time fortunately the Java Broker WebSocket transport is actually
+tolerant of this off-spec. behaviour. My personal view is that both approaches
+should be valid and in particular using the standard TCP framing means that it
+is straightforward to create WebSocket<->TCP proxies, which is useful given that
+only the Java Broker currently has a native WebSocket transport.
 
-The example send-async.c and recv-async.c are both pretty hacky at the moment.
 
-proton-j seems to use hawt-dispatch, which is modelled after Grand Central Dispatch so I need to
-work out what it's using it do do and whether there are parallels in proton-c

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2cf80a9e/proton-c/bindings/javascript/binding-close.js
----------------------------------------------------------------------
diff --git a/proton-c/bindings/javascript/binding-close.js b/proton-c/bindings/javascript/binding-close.js
index b7f1d93..07b68c2 100644
--- a/proton-c/bindings/javascript/binding-close.js
+++ b/proton-c/bindings/javascript/binding-close.js
@@ -18,10 +18,16 @@
  *
  */
 
-// These values are essentially constants sitting in the proton namespace.
-// We have to set them after pn_get_version_major/pn_get_version_minor have been
-// defined so we must do it here in binding-close.js as it's a --post-js block.
+/**
+ * These values are essentially constants sitting in the proton namespace
+ * that is to say they will be exported via:
+ * proton.VERSION_MAJOR
+ * proton.VERSION_MINOR
+ * We have to set them after pn_get_version_major/pn_get_version_minor have been
+ * defined so we must do it here in binding-close.js as it's a --post-js block.
+ */
 Module['VERSION_MAJOR'] = _pn_get_version_major();
 Module['VERSION_MINOR'] = _pn_get_version_minor();
 
 })(); // End of self calling lambda used to wrap library.
+

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2cf80a9e/proton-c/bindings/javascript/module.js
----------------------------------------------------------------------
diff --git a/proton-c/bindings/javascript/module.js b/proton-c/bindings/javascript/module.js
index 0fdb803..cf64700 100644
--- a/proton-c/bindings/javascript/module.js
+++ b/proton-c/bindings/javascript/module.js
@@ -19,9 +19,13 @@
  */
 
 /**
- * This file provides a JavaScript wrapper around the Proton Messenger API.
- * It will be used to wrap the emscripten compiled proton-c code and be minified by
- * the Closure compiler, so all comments will be stripped from the actual library.
+ * This file defines the Module Object which provides a namespace around the Proton
+ * Messenger API. The Module object is used extensively by the emscripten runtime,
+ * however for convenience it is exported with the name "proton" and not "Module".
+ * <p>
+ * The emscripten compiled proton-c code and the JavaScript binding code will be 
+ * minified by the Closure compiler, so all comments will be stripped from the
+ * actual library.
  * <p>
  * This JavaScript wrapper provides a somewhat more idiomatic object oriented
  * interface which abstracts the low-level emscripten based implementation details
@@ -32,25 +36,50 @@
 /**
  * The Module Object is exported by emscripten for all execution platforms, we
  * use it as a namespace to allow us to selectively export only what we wish to
- * be publicly visible from this package/module.
+ * be publicly visible from this package/module, which is wrapped in a closure.
  * <p>
  * Internally the binding code uses the associative array form for declaring
  * exported properties to prevent the Closure compiler from minifying e.g.
  * <pre>Module['Messenger'] = ...</pre>
- * Exported Objects can be used in client code using a more convenient namespace, e.g.:
+ * Exported Objects can however be used in client code using a more convenient
+ * and obvious proton namespace, e.g.:
  * <pre>
- * proton = require('qpid-proton');
+ * var proton = require('qpid-proton');
  * var messenger = new proton.Messenger();
  * var message = new proton.Message();
+ * ...
+ * </pre>
+ * The core part of this library is actually proton-c compiled into JavaScript.
+ * In order to provide C style memory management (malloc/free) emscripten uses
+ * a "virtual heap", which is actually a pre-allocated ArrayBuffer. The size of
+ * this virtual heap is set as part of the runtime initialisation and cannot be
+ * changed subsequently (the default size is 16*1024*1024 = 16777216).
+ * <p>
+ * Applications can specify the size of virtual heap that they require via the
+ * global variable PROTON_HEAP_SIZE, this must be set <b>before</b> the library is
+ * loaded e.g. in Node.js an application would do:
+ * <pre>
+ * PROTON_HEAP_SIZE = 50000000; // Note no var - it needs to be global.
+ * var proton = require('qpid-proton');
+ * ...
+ * </pre>
+ * A browser based application would do:
+ * <pre>
+ * &lt;script type="text/javascript"&gt;PROTON_HEAP_SIZE = 50000000;&lt;/script&gt;
+ * &lt;script type="text/javascript" src="proton.js">&lt;/script&gt;
  * </pre>
  * @namespace proton
  */
+var Module = {};
 
-var Module = {
-    // Prevent emscripten runtime exiting, we will be enabling network callbacks.
-    'noExitRuntime' : true,
-};
-
+// If the global variable PROTON_HEAP_SIZE has been set by the application this
+// will result in the emscripten heap getting set to the next multiple of
+// 16777216 above PROTON_HEAP_SIZE.
+if (typeof process === 'object' && typeof require === 'function' && global['PROTON_HEAP_SIZE']) {
+    Module['TOTAL_MEMORY'] = global['PROTON_HEAP_SIZE'];
+} else if (typeof window === 'object' && window['PROTON_HEAP_SIZE']) {
+    Module['TOTAL_MEMORY'] = window['PROTON_HEAP_SIZE'];
+}
 
 /*****************************************************************************/
 /*                                                                           */


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org