blob: 316a1f0961ea3c063b386d6ff4f3ec9de9da0d96 [file] [log] [blame]
/**
* @author: Wentao Shang
* See COPYING for copyright and distribution information.
*/
var WebSocketTransport = function WebSocketTransport() {
this.ws = null;
this.connectedHost = null;
this.connectedPort = null;
this.elementReader = null;
this.defaultGetHostAndPort = NDN.makeShuffledGetHostAndPort
(["A.ws.ndn.ucla.edu", "B.ws.ndn.ucla.edu", "C.ws.ndn.ucla.edu", "D.ws.ndn.ucla.edu",
"E.ws.ndn.ucla.edu"],
9696);
};
WebSocketTransport.prototype.connect = function(ndn, onopenCallback) {
if (this.ws != null)
delete this.ws;
this.ws = new WebSocket('ws://' + ndn.host + ':' + ndn.port);
if (LOG > 0) console.log('ws connection created.');
this.connectedHost = ndn.host;
this.connectedPort = ndn.port;
this.ws.binaryType = "arraybuffer";
this.elementReader = new BinaryXmlElementReader(ndn);
var self = this;
this.ws.onmessage = function(ev) {
var result = ev.data;
//console.log('RecvHandle called.');
if(result == null || result == undefined || result == "" ) {
console.log('INVALID ANSWER');
} else if (result instanceof ArrayBuffer) {
var bytearray = new Uint8Array(result);
if (LOG>3) console.log('BINARY RESPONSE IS ' + DataUtils.toHex(bytearray));
try {
// Find the end of the binary XML element and call ndn.onReceivedElement.
self.elementReader.onReceivedData(bytearray);
} catch (ex) {
console.log("NDN.ws.onmessage exception: " + ex);
return;
}
}
}
this.ws.onopen = function(ev) {
if (LOG > 3) console.log(ev);
if (LOG > 3) console.log('ws.onopen: WebSocket connection opened.');
if (LOG > 3) console.log('ws.onopen: ReadyState: ' + this.readyState);
// NDN.registerPrefix will fetch the ccndid when needed.
onopenCallback();
}
this.ws.onerror = function(ev) {
console.log('ws.onerror: ReadyState: ' + this.readyState);
console.log(ev);
console.log('ws.onerror: WebSocket error: ' + ev.data);
}
this.ws.onclose = function(ev) {
console.log('ws.onclose: WebSocket connection closed.');
self.ws = null;
// Close NDN when WebSocket is closed
ndn.readyStatus = NDN.CLOSED;
ndn.onclose();
//console.log("NDN.onclose event fired.");
}
};
/*
* Send the Uint8Array data.
*/
WebSocketTransport.prototype.send = function(data) {
if (this.ws != null) {
// If we directly use data.buffer to feed ws.send(),
// WebSocket may end up sending a packet with 10000 bytes of data.
// That is, WebSocket will flush the entire buffer
// regardless of the offset of the Uint8Array. So we have to create
// a new Uint8Array buffer with just the right size and copy the
// content from binaryInterest to the new buffer.
// ---Wentao
var bytearray = new Uint8Array(data.length);
bytearray.set(data);
this.ws.send(bytearray.buffer);
if (LOG > 3) console.log('ws.send() returned.');
}
else
console.log('WebSocket connection is not established.');
}
WebSocketTransport.prototype.expressInterest = function(ndn, interest, closure) {
if (this.ws == null || this.connectedHost != ndn.host || this.connectedPort != ndn.port) {
var self = this;
this.connect(ndn, function() { self.expressInterestHelper(ndn, interest, closure); });
}
else
this.expressInterestHelper(ndn, interest, closure);
};
WebSocketTransport.prototype.expressInterestHelper = function(ndn, interest, closure) {
//TODO: check local content store first
if (closure != null) {
var pitEntry = new PITEntry(interest, closure);
// TODO: This needs to be a single thread-safe transaction on a global object.
NDN.PITTable.push(pitEntry);
closure.pitEntry = pitEntry;
}
// Set interest timer
if (closure != null) {
pitEntry.timerID = setTimeout(function() {
if (LOG > 3) console.log("Interest time out.");
// Remove PIT entry from NDN.PITTable.
// TODO: Make this a thread-safe operation on the global PITTable.
var index = NDN.PITTable.indexOf(pitEntry);
//console.log(NDN.PITTable);
if (index >= 0)
NDN.PITTable.splice(index, 1);
//console.log(NDN.PITTable);
//console.log(pitEntry.interest.name.getName());
// Raise closure callback
closure.upcall(Closure.UPCALL_INTEREST_TIMED_OUT, new UpcallInfo(ndn, interest, 0, null));
}, interest.interestLifetime); // interestLifetime is in milliseconds.
//console.log(closure.timerID);
}
this.send(encodeToBinaryInterest(interest));
};