| <?xml version = "1.0" encoding="utf-8" ?> | |
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" | |
| "DTD/xhtml1-strict.dtd"> | |
| <html xmlns = "http://www.w3.org/1999/xhtml"> | |
| <meta charset="UTF-8"> | |
| <head> | |
| <title>NDN Get File via WebSocket</title> | |
| <script type="text/javascript" src="../tools/build/ndn-js.js"></script> | |
| <script type="text/javascript"> | |
| hostip = "131.179.196.232"; | |
| //hostip = "localhost"; | |
| //var ndncon = new NDN({port:9696,host:hostip}); | |
| var ndncon = new NDN({port:9696,host:hostip,verify:false}); | |
| ndncon.transport.connectWebSocket(ndncon); | |
| /////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| /* | |
| * Closure for calling expressInterest to fetch big file. | |
| */ | |
| var ContentClosure = function ContentClosure(ndn, T0) { | |
| // Inherit from Closure. | |
| Closure.call(this); | |
| this.T0 = T0; | |
| this.ndn = ndn; | |
| this.totalBlocks = 0; | |
| this.firstReceivedSegmentNumber = null; | |
| this.firstReceivedContentObject = null; | |
| } | |
| ContentClosure.prototype.upcall = function(kind, upcallInfo) { | |
| if (kind == Closure.UPCALL_INTEREST_TIMED_OUT) { | |
| var T1 = new Date(); | |
| document.getElementById('content').innerHTML += "<p>Interest time out.</p>"; | |
| document.getElementById('content').innerHTML += "<p>Time elapsed: " + (T1 - this.T0) + " ms including 4s timeout</p>"; | |
| document.getElementById('content').innerHTML += "<p>Total number of blocks: " + this.totalBlocks + "</p>"; | |
| return Closure.RESULT_OK; | |
| } | |
| if (kind == Closure.UPCALL_CONTENT_BAD) { | |
| console.log("NdnProtocol.ContentClosure: signature verification failed"); | |
| console.log(upcallInfo.contentObject.name.getName()); | |
| console.log(DataUtils.toHex(upcallInfo.contentObject.signature.Witness).toLowerCase()); | |
| return Closure.RESULT_OK; | |
| } | |
| if (!(kind == Closure.UPCALL_CONTENT || | |
| kind == Closure.UPCALL_CONTENT_UNVERIFIED)) | |
| // The upcall is not for us. | |
| return Closure.RESULT_ERR; | |
| var contentObject = upcallInfo.contentObject; | |
| if (contentObject.content == null) { | |
| console.log("NdnProtocol.ContentClosure: contentObject.content is null"); | |
| return Closure.RESULT_ERR; | |
| } | |
| // Use the segmentNumber to load multiple segments. | |
| //var segmentNumber = ArrayToNum(contentObject.name.components[contentObject.name.components.length - 1]); | |
| var segmentNumber = DataUtils.bigEndianToUnsignedInt | |
| (contentObject.name.components[contentObject.name.components.length - 1]); | |
| //console.log(segmentNumber); | |
| if (this.firstReceivedSegmentNumber == null) { | |
| // This is the first call. | |
| this.firstReceivedSegmentNumber = segmentNumber; | |
| if (segmentNumber != 0) { | |
| // Special case: Save this content object for later and request segment zero. | |
| this.firstReceivedContentObject = contentObject; | |
| var componentsForZero = contentObject.name.components.slice | |
| (0, contentObject.name.components.length - 1); | |
| componentsForZero.push([0]); | |
| this.ndn.expressInterest(new Name(componentsForZero), this); | |
| return Closure.RESULT_OK; | |
| } | |
| } | |
| // Process received data here... | |
| // Count content length | |
| //nameStr = escape(contentObject.name.getName()); | |
| //document.getElementById('content').innerHTML += "<p>Name string: " + nameStr + "</p>"; | |
| //document.getElementById('content').innerHTML += "<p>Content buffer length: " + contentObject.content.length + "</p>"; | |
| this.totalBlocks++; | |
| // Check for the special case if the saved content is for the next segment that we need. | |
| if (this.firstReceivedContentObject != null && | |
| this.firstReceivedSegmentNumber == segmentNumber + 1) { | |
| // Substitute the saved contentObject send its content and keep going. | |
| contentObject = this.firstReceivedContentObject; | |
| segmentNumber = segmentNumber + 1; | |
| // Clear firstReceivedContentObject to save memory. | |
| this.firstReceivedContentObject = null; | |
| // Process received data here... | |
| // Count content length | |
| //nameStr = escape(contentObject.name.getName()); | |
| //document.getElementById('content').innerHTML += "<p>Name string: " + nameStr + "</p>"; | |
| //document.getElementById('content').innerHTML += "<p>Content buffer length: " + contentObject.content.length + "</p>"; | |
| this.totalBlocks++; | |
| } | |
| var finalSegmentNumber = null; | |
| if (contentObject.signedInfo != null && contentObject.signedInfo.finalBlockID != null) | |
| //finalSegmentNumber = ArrayToNum(contentObject.signedInfo.finalBlockID); | |
| finalSegmentNumber = DataUtils.bigEndianToUnsignedInt(contentObject.signedInfo.finalBlockID); | |
| if (finalSegmentNumber == null || segmentNumber != finalSegmentNumber) { | |
| // Make a name for the next segment and get it. | |
| //var segmentNumberPlus1 = NumToArray(segmentNumber + 1); | |
| // Make a name for the next segment and get it. | |
| var segmentNumberPlus1 = DataUtils.nonNegativeIntToBigEndian(segmentNumber + 1); | |
| // Put a 0 byte in front. | |
| var nextSegmentNumber = new Uint8Array(segmentNumberPlus1.length + 1); | |
| nextSegmentNumber.set(segmentNumberPlus1, 1); | |
| var components = contentObject.name.components.slice | |
| (0, contentObject.name.components.length - 1); | |
| components.push(nextSegmentNumber); | |
| //components.push(segmentNumberPlus1); | |
| this.ndn.expressInterest(new Name(components), this); | |
| } | |
| else { | |
| // Final block received. | |
| // Record stop time | |
| var T1 = new Date(); | |
| document.getElementById('content').innerHTML += "<p>Final block received.</p>"; | |
| document.getElementById('content').innerHTML += "<p>Time elapsed: " + (T1 - this.T0) + " ms</p>"; | |
| document.getElementById('content').innerHTML += "<p>Total number of blocks: " + this.totalBlocks + "</p>"; | |
| } | |
| return Closure.RESULT_OK; | |
| }; | |
| /* | |
| * Convert the big endian Uint8Array to an unsigned int. | |
| * Don't check for overflow. | |
| */ | |
| function ArrayToNum(bytes) { | |
| var result = 0; | |
| for (var i = 0; i < bytes.length; ++i) { | |
| result = result * 10; | |
| result += (bytes[i] - 48); | |
| } | |
| return result; | |
| }; | |
| /* | |
| * Convert the int value to a new big endian Uint8Array and return. | |
| * If value is 0 or negative, return Uint8Array(0). | |
| */ | |
| function NumToArray(value) { | |
| value = Math.round(value); | |
| if (value <= 0) | |
| return new Uint8Array(0); | |
| numString = value.toString(); | |
| var size = numString.length; | |
| var result = new Uint8Array(size); | |
| for (i = 0; i < size; i++) { | |
| result[i] = numString.charCodeAt(i); | |
| } | |
| return result; | |
| }; | |
| /////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| /* | |
| var AsyncGetClosure = function AsyncGetClosure(T0) { | |
| this.T0 = T0; // Start time | |
| // Inherit from Closure. | |
| Closure.call(this); | |
| }; | |
| AsyncGetClosure.prototype.upcall = function(kind, upcallInfo) { | |
| //console.log("Closure.upcall() executed."); | |
| if (kind == Closure.UPCALL_FINAL) { | |
| // Do nothing. | |
| } else if (kind == Closure.UPCALL_CONTENT) { | |
| var T1 = new Date(); | |
| var content = upcallInfo.contentObject; | |
| nameStr = escape(content.name.getName()); | |
| document.getElementById('content').innerHTML += "<p>Time elapsed: " + (T1 - this.T0) + " ms</p>"; | |
| document.getElementById('content').innerHTML += "<p>Name string: " + nameStr + "</p>"; | |
| document.getElementById('content').innerHTML += "<p>Content buffer length: " + content.content.length + "</p>"; | |
| //console.log("In callback, nameStr: " + nameStr); | |
| //console.log("In callback, content: "); | |
| //console.log(content.content.length); | |
| //document.getElementById('content').innerHTML += contentObjectToHtml(content); | |
| } else if (kind == Closure.UPCALL_INTEREST_TIMED_OUT) { | |
| console.log("Closure.upcall called with interest time out."); | |
| } | |
| return Closure.RESULT_OK; | |
| }; | |
| */ | |
| function run() { | |
| document.getElementById('content').innerHTML += "<p>Started...</p>"; | |
| //ndn.expressInterest(new Name(document.getElementById('interest').value), new AsyncGetClosure( new Date() )); | |
| var name = new Name(document.getElementById('interest').value); | |
| ndncon.expressInterest( name, | |
| new ContentClosure( ndncon, new Date() )); | |
| } | |
| </script> | |
| </head> | |
| <body > | |
| <form> | |
| Please Enter an Interest:<br /> | |
| <input id="interest" type="text" name="INTEREST" size="50" value="/wentao.shang/choir_jail.png" /> | |
| </form> | |
| <button onclick="run()">Fetch Content</button> | |
| <p id="content">Result: <br/></p> | |
| </body> | |
| </html> |