<?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}); | |
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 || | |
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\n"); | |
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> |