Meki Cherkaoui | f2e96ed | 2012-04-22 16:21:27 -0700 | [diff] [blame] | 1 | |
Jeff Burke | 004039b | 2012-12-08 11:31:37 -0800 | [diff] [blame] | 2 | NDN.JS: A javascript client library for Named Data Networking |
| 3 | -------------------------------------------------------------- |
Meki Cherkaoui | f2e96ed | 2012-04-22 16:21:27 -0700 | [diff] [blame] | 4 | |
Jeff Burke | 169445b | 2012-12-08 12:15:54 -0800 | [diff] [blame] | 5 | NDN.JS is the first native version of the NDN protocol written in JavaScript. It is wire |
| 6 | format compatible with PARC's CCNx. |
Meki Cherkaoui | f2e96ed | 2012-04-22 16:21:27 -0700 | [diff] [blame] | 7 | |
Jeff Burke | 004039b | 2012-12-08 11:31:37 -0800 | [diff] [blame] | 8 | The project by the UCLA NDN team - for more information on NDN, see |
| 9 | http://named-data.net/ |
| 10 | http://ndn.ucla.edu/ |
| 11 | |
Jeff Burke | 169445b | 2012-12-08 12:15:54 -0800 | [diff] [blame] | 12 | NDN.JS is open source under a license described in the file COPYING. While the license |
| 13 | does not require it, we really would appreciate it if others would share their |
| 14 | contributions to the library if they are willing to do so under the same license. |
Meki Cherkaoui | f2e96ed | 2012-04-22 16:21:27 -0700 | [diff] [blame] | 15 | |
Jeff Burke | 004039b | 2012-12-08 11:31:37 -0800 | [diff] [blame] | 16 | --- |
| 17 | |
Jeff Burke | 169445b | 2012-12-08 12:15:54 -0800 | [diff] [blame] | 18 | This is a young project, with minimal documentation that we are slowly enhancing. Please |
| 19 | email Jeff Burke (jburke@remap.ucla.edu) with any questions. |
Jeff Burke | 004039b | 2012-12-08 11:31:37 -0800 | [diff] [blame] | 20 | |
Jeff Burke | 169445b | 2012-12-08 12:15:54 -0800 | [diff] [blame] | 21 | The primary goal of NDN.JS is to provide a pure Javascript implementation of the NDN API |
| 22 | that enables developers to create browser-based applications using Named Data Networking. |
| 23 | The approach requires no native code or signed Java applets, and thus can be delivered |
| 24 | over the current web to modern browsers with no hassle for the end user. |
Jeff Burke | 004039b | 2012-12-08 11:31:37 -0800 | [diff] [blame] | 25 | |
| 26 | Additional goals for the project: |
Jeff Burke | 169445b | 2012-12-08 12:15:54 -0800 | [diff] [blame] | 27 | - Websockets transport (rather than TCP or UDP, which are not directly supported in |
| 28 | Javascript). |
Jeff Burke | 858c07a | 2012-12-08 11:35:25 -0800 | [diff] [blame] | 29 | - Relatively lightweight and compact, to enable efficient use on the web. |
| 30 | - Wire format compatible with PARC's CCNx implementation of NDN. |
Jeff Burke | 004039b | 2012-12-08 11:31:37 -0800 | [diff] [blame] | 31 | |
Jeff Burke | 169445b | 2012-12-08 12:15:54 -0800 | [diff] [blame] | 32 | The library currently requires a remote NDN daemon, and has been tested with ccnd, from |
| 33 | the's CCNx package: http://ccnx.org/ |
Jeff Burke | 004039b | 2012-12-08 11:31:37 -0800 | [diff] [blame] | 34 | |
| 35 | Currently, the library has two APIs for developers: |
| 36 | |
| 37 | 1. The Javascript API for asynchronous Interest/Data exchange. |
| 38 | This uses WebSockets for transport and currently requires a |
| 39 | proxy for communication with a remote ccnd daemon. |
| 40 | |
| 41 | 2. A Firefox plug-in, which implements an "ndn:/" url scheme |
| 42 | following CCNx repository conventions for file retrieval. |
| 43 | |
Jeff Burke | 169445b | 2012-12-08 12:15:54 -0800 | [diff] [blame] | 44 | By default, both parts of the library connect automatically to a set of proxies and hubs |
| 45 | that are part of the NDN research project's testbed. http://named-data.net/testbed.html |
| 46 | There are currently no restrictions on non-commercial, research-oriented data exchange on |
| 47 | this testbed. (Contact jburke@remap.ucla.edu for more details.) The developer can also |
| 48 | specify a local or remote ccnd as well, as an argument to the NDN constructor. |
Jeff Burke | 004039b | 2012-12-08 11:31:37 -0800 | [diff] [blame] | 49 | |
| 50 | |
| 51 | |
| 52 | JAVASCRIPT API |
| 53 | -------------- |
| 54 | |
Jeff Burke | 3354610 | 2012-12-08 11:55:36 -0800 | [diff] [blame] | 55 | See files in js/ and examples in js/testing, js/examples |
Jeff Burke | 004039b | 2012-12-08 11:31:37 -0800 | [diff] [blame] | 56 | |
Jeff Burke | 169445b | 2012-12-08 12:15:54 -0800 | [diff] [blame] | 57 | NDN.JS currently supports expressing Interests (and receiving data) and publishing Data |
| 58 | (that answers Interests). This includes encoding and decoding data packets as well as |
| 59 | signing and verifying them using RSA keys. |
Jeff Burke | 004039b | 2012-12-08 11:31:37 -0800 | [diff] [blame] | 60 | |
Jeff Burke | 3354610 | 2012-12-08 11:55:36 -0800 | [diff] [blame] | 61 | ** NDN connectivity ** |
Jeff Burke | 169445b | 2012-12-08 12:15:54 -0800 | [diff] [blame] | 62 | The only way (for now) to get connectivity to other NDN nodes is via ccnd. For the |
| 63 | Javascript API, a Websockets proxy that can communicate the target ccnd is currently |
| 64 | required. Code for such a proxy (using Node.js) is in the wsproxy directory. It |
| 65 | currently listens on port 9696 and passes messages (using either TCP or UDP) to ccnd on |
| 66 | the same host. |
Jeff Burke | 858c07a | 2012-12-08 11:35:25 -0800 | [diff] [blame] | 67 | |
Jeff Burke | 3354610 | 2012-12-08 11:55:36 -0800 | [diff] [blame] | 68 | ** Including the scripts in a web page ** |
| 69 | To use NDN.JS in a web page, one of two scripts must be included using a <script> tag: |
| 70 | |
Jeff Burke | 169445b | 2012-12-08 12:15:54 -0800 | [diff] [blame] | 71 | 1. ndn-js.js, a combined, compressed library designed for efficient distribution. It can |
| 72 | be built using js/tools/build/make-js.sh This is used in examples/ndn-ping.html |
Jeff Burke | 3354610 | 2012-12-08 11:55:36 -0800 | [diff] [blame] | 73 | |
Jeff Burke | 169445b | 2012-12-08 12:15:54 -0800 | [diff] [blame] | 74 | 2. Helper.js, which loads each component script independently. This is used in most of |
| 75 | the tests in testing/ |
Jeff Burke | 3354610 | 2012-12-08 11:55:36 -0800 | [diff] [blame] | 76 | |
Jeff Burke | 018707d | 2012-12-08 12:23:39 -0800 | [diff] [blame] | 77 | ** Example to retrieve content ** |
Jeff Burke | 004039b | 2012-12-08 11:31:37 -0800 | [diff] [blame] | 78 | A simple example of the current API to express an Interest and receive data: |
| 79 | |
Jeff Burke | 858c07a | 2012-12-08 11:35:25 -0800 | [diff] [blame] | 80 | var ndn = new NDN(); // connect to a default hub/proxy |
Jeff Thompson | b68ceab | 2012-11-25 18:25:56 -0800 | [diff] [blame] | 81 | ndn.transport.connectWebSocket(ndn); |
| 82 | |
| 83 | var AsyncGetClosure = function AsyncGetClosure() { |
| 84 | // Inherit from Closure. |
| 85 | Closure.call(this); |
| 86 | }; |
| 87 | AsyncGetClosure.prototype.upcall = function(kind, upcallInfo) { |
| 88 | if (kind == Closure.UPCALL_CONTENT) { |
| 89 | console.log("Received " + upcallInfo.contentObject.name.to_uri()); |
| 90 | console.log(upcallInfo.contentObject.content); |
| 91 | } |
| 92 | return Closure.RESULT_OK; |
| 93 | }; |
Jeff Thompson | 9e6dff0 | 2012-11-04 09:20:47 -0800 | [diff] [blame] | 94 | |
Jeff Burke | 169445b | 2012-12-08 12:15:54 -0800 | [diff] [blame] | 95 | ndn.expressInterest(new Name("/ndn/ucla.edu/apps/ndn-js-test/hello.txt"), new |
| 96 | AsyncGetClosure()); |
Jeff Thompson | 9e6dff0 | 2012-11-04 09:20:47 -0800 | [diff] [blame] | 97 | |
Jeff Burke | 018707d | 2012-12-08 12:23:39 -0800 | [diff] [blame] | 98 | ** Example to publish content ** |
| 99 | |
| 100 | // Note that publishing content requires knowledge of a |
| 101 | // routable prefix for your upstream ccnd. We are working |
| 102 | // on a way to either obtain that prefix or use the /local |
| 103 | // convention. |
| 104 | |
| 105 | For now, see testing/test-publish-async.html |
| 106 | |
| 107 | |
| 108 | |
Jeff Thompson | b68ceab | 2012-11-25 18:25:56 -0800 | [diff] [blame] | 109 | |
Jeff Burke | 004039b | 2012-12-08 11:31:37 -0800 | [diff] [blame] | 110 | FIREFOX ADD-ON FOR THE NDN PROTOCOL |
| 111 | ----------------------------------- |
| 112 | |
| 113 | See files in js/ndnProtocol |
| 114 | |
Jeff Burke | 169445b | 2012-12-08 12:15:54 -0800 | [diff] [blame] | 115 | NDN.JS includes a Firefox extension for the ndn protocol built using the Javascript |
| 116 | library. It currently obtains NDN connectivity through the NDN testbed. (This is |
| 117 | hard-coded.) |
Jeff Burke | 004039b | 2012-12-08 11:31:37 -0800 | [diff] [blame] | 118 | |
| 119 | To install, either download |
Jeff Thompson | bd82926 | 2012-11-30 22:28:37 -0800 | [diff] [blame] | 120 | https://github.com/remap/ndn-js/blob/master/js/ndnProtocol.xpi |
| 121 | or use js/ndnProtocol.xpi in the distribution. In Firefox, open |
Jeff Thompson | 9e6dff0 | 2012-11-04 09:20:47 -0800 | [diff] [blame] | 122 | Tools > Add-ons. In the "gear" or "wrench" menu, click Install Add-on From File and open |
Jeff Thompson | bd82926 | 2012-11-30 22:28:37 -0800 | [diff] [blame] | 123 | ndnProtocol.xpi. Restart Firefox. |
Jeff Thompson | 9e6dff0 | 2012-11-04 09:20:47 -0800 | [diff] [blame] | 124 | |
Jeff Thompson | bd82926 | 2012-11-30 22:28:37 -0800 | [diff] [blame] | 125 | Firefox uses the protocol extension to load any URI starting with ndn, for example |
| 126 | ndn:/ndn/ucla.edu/apps/lwndn-test/trig-table |
Jeff Thompson | 9e6dff0 | 2012-11-04 09:20:47 -0800 | [diff] [blame] | 127 | |
Jeff Burke | 169445b | 2012-12-08 12:15:54 -0800 | [diff] [blame] | 128 | When the page is loaded, Firefox updates the address bar with the full matched name from |
| 129 | the retrieved content object including the version, but without the implicit digest or |
| 130 | segment number (see below). |
Jeff Burke | 3354610 | 2012-12-08 11:55:36 -0800 | [diff] [blame] | 131 | |
| 132 | |
| 133 | |
Jeff Thompson | 9e6dff0 | 2012-11-04 09:20:47 -0800 | [diff] [blame] | 134 | |
Jeff Burke | 004039b | 2012-12-08 11:31:37 -0800 | [diff] [blame] | 135 | * Interest selectors in the ndn protocol: |
Jeff Thompson | b68ceab | 2012-11-25 18:25:56 -0800 | [diff] [blame] | 136 | |
Jeff Burke | 169445b | 2012-12-08 12:15:54 -0800 | [diff] [blame] | 137 | You can add interest selectors. For example, this uses 1 to select the "rightmost" child |
| 138 | (latest version). |
Jeff Thompson | bd82926 | 2012-11-30 22:28:37 -0800 | [diff] [blame] | 139 | ndn:/ndn/ucla.edu/apps/ndn-js-test/hello.txt?ndn.ChildSelector=1&key=value#ref |
Jeff Thompson | b68ceab | 2012-11-25 18:25:56 -0800 | [diff] [blame] | 140 | |
| 141 | The browser loads the latest version and changes the address to: |
Jeff Thompson | bd82926 | 2012-11-30 22:28:37 -0800 | [diff] [blame] | 142 | ndn:/ndn/ucla.edu/apps/ndn-js-test/hello.txt/%FD%05%0B%16z%22%D1?key=value#ref |
Jeff Thompson | b68ceab | 2012-11-25 18:25:56 -0800 | [diff] [blame] | 143 | |
Jeff Thompson | bd82926 | 2012-11-30 22:28:37 -0800 | [diff] [blame] | 144 | The child selector was used and removed. Note that the other non-ndn query values and |
Jeff Thompson | b68ceab | 2012-11-25 18:25:56 -0800 | [diff] [blame] | 145 | ref "?key=value#ref" are still present, in case they are needed by the web application. |
| 146 | |
| 147 | The following selector keys are supported: |
Jeff Thompson | bd82926 | 2012-11-30 22:28:37 -0800 | [diff] [blame] | 148 | ndn.MinSuffixComponent= non-negative int |
| 149 | ndn.MaxSuffixComponents= non-negative int |
| 150 | ndn.ChildSelector= non-negative int |
| 151 | ndn.AnswerOriginKind= non-negative int |
| 152 | ndn.Scope= non-negative int |
Jeff Thompson | 42806a1 | 2012-12-29 18:19:39 -0800 | [diff] [blame^] | 153 | ndn.InterestLifetime= non-negative int (milliseconds) |
Jeff Thompson | bd82926 | 2012-11-30 22:28:37 -0800 | [diff] [blame] | 154 | ndn.PublisherPublicKeyDigest= % escaped value |
| 155 | ndn.Nonce= % escaped value |
Jeff Thompson | b68ceab | 2012-11-25 18:25:56 -0800 | [diff] [blame] | 156 | |
Jeff Thompson | bd82926 | 2012-11-30 22:28:37 -0800 | [diff] [blame] | 157 | TODO: implement ndn.Exclude. |
Jeff Thompson | b68ceab | 2012-11-25 18:25:56 -0800 | [diff] [blame] | 158 | |
Jeff Thompson | bd82926 | 2012-11-30 22:28:37 -0800 | [diff] [blame] | 159 | * Multiple segments in the ndn protocol |
Jeff Thompson | b68ceab | 2012-11-25 18:25:56 -0800 | [diff] [blame] | 160 | |
Jeff Burke | 169445b | 2012-12-08 12:15:54 -0800 | [diff] [blame] | 161 | A URI for content with multiple segments is handled as follows. If the URI has a segment |
| 162 | number, just retrieve that segment and return the content to the browser. |
Jeff Thompson | 9e6dff0 | 2012-11-04 09:20:47 -0800 | [diff] [blame] | 163 | |
Jeff Burke | 169445b | 2012-12-08 12:15:54 -0800 | [diff] [blame] | 164 | Otherwise look at the name in the returned ContentObject. If the returned name has no |
| 165 | segment number, just return the content to the browser. If the name has a segment number |
| 166 | which isn't 0, store it and express an interest for segment 0. Read segments in order and |
| 167 | return each content to the browser as we go until we get the segment for FinalBlockID. |
Jeff Thompson | 9e6dff0 | 2012-11-04 09:20:47 -0800 | [diff] [blame] | 168 | |