blob: 316a1f0961ea3c063b386d6ff4f3ec9de9da0d96 [file] [log] [blame]
Wentao Shangc0311e52012-12-03 10:38:23 -08001/**
Jeff Thompson5b265a72012-11-12 01:13:08 -08002 * @author: Wentao Shang
3 * See COPYING for copyright and distribution information.
Jeff Thompson5b265a72012-11-12 01:13:08 -08004 */
5
6var WebSocketTransport = function WebSocketTransport() {
7 this.ws = null;
Jeff Thompsond771b122013-01-26 19:04:41 -08008 this.connectedHost = null;
9 this.connectedPort = null;
Jeff Thompsonbb9802d2013-01-20 23:54:18 -080010 this.elementReader = null;
Jeff Thompsonc881b552012-12-14 01:29:12 -080011 this.defaultGetHostAndPort = NDN.makeShuffledGetHostAndPort
12 (["A.ws.ndn.ucla.edu", "B.ws.ndn.ucla.edu", "C.ws.ndn.ucla.edu", "D.ws.ndn.ucla.edu",
13 "E.ws.ndn.ucla.edu"],
14 9696);
Jeff Thompson5b265a72012-11-12 01:13:08 -080015};
16
Jeff Thompsond771b122013-01-26 19:04:41 -080017WebSocketTransport.prototype.connect = function(ndn, onopenCallback) {
Jeff Thompson5b265a72012-11-12 01:13:08 -080018 if (this.ws != null)
19 delete this.ws;
20
21 this.ws = new WebSocket('ws://' + ndn.host + ':' + ndn.port);
Jeff Thompson3c263812012-12-01 17:20:28 -080022 if (LOG > 0) console.log('ws connection created.');
Jeff Thompsond771b122013-01-26 19:04:41 -080023 this.connectedHost = ndn.host;
24 this.connectedPort = ndn.port;
Jeff Thompson5b265a72012-11-12 01:13:08 -080025
26 this.ws.binaryType = "arraybuffer";
27
Jeff Thompsonbb9802d2013-01-20 23:54:18 -080028 this.elementReader = new BinaryXmlElementReader(ndn);
Jeff Thompson5b265a72012-11-12 01:13:08 -080029 var self = this;
30 this.ws.onmessage = function(ev) {
31 var result = ev.data;
32 //console.log('RecvHandle called.');
33
34 if(result == null || result == undefined || result == "" ) {
35 console.log('INVALID ANSWER');
36 } else if (result instanceof ArrayBuffer) {
37 var bytearray = new Uint8Array(result);
38
Jeff Thompson13c2e7b2012-12-01 17:33:30 -080039 if (LOG>3) console.log('BINARY RESPONSE IS ' + DataUtils.toHex(bytearray));
Jeff Thompson5b265a72012-11-12 01:13:08 -080040
41 try {
Jeff Thompsonbb9802d2013-01-20 23:54:18 -080042 // Find the end of the binary XML element and call ndn.onReceivedElement.
43 self.elementReader.onReceivedData(bytearray);
Jeff Thompson5b265a72012-11-12 01:13:08 -080044 } catch (ex) {
45 console.log("NDN.ws.onmessage exception: " + ex);
46 return;
47 }
Jeff Thompson5b265a72012-11-12 01:13:08 -080048 }
49 }
50
51 this.ws.onopen = function(ev) {
Jeff Thompson3c263812012-12-01 17:20:28 -080052 if (LOG > 3) console.log(ev);
53 if (LOG > 3) console.log('ws.onopen: WebSocket connection opened.');
54 if (LOG > 3) console.log('ws.onopen: ReadyState: ' + this.readyState);
Jeff Thompsond771b122013-01-26 19:04:41 -080055 // NDN.registerPrefix will fetch the ccndid when needed.
56
57 onopenCallback();
Jeff Thompson5b265a72012-11-12 01:13:08 -080058 }
59
60 this.ws.onerror = function(ev) {
61 console.log('ws.onerror: ReadyState: ' + this.readyState);
62 console.log(ev);
63 console.log('ws.onerror: WebSocket error: ' + ev.data);
64 }
65
66 this.ws.onclose = function(ev) {
67 console.log('ws.onclose: WebSocket connection closed.');
68 self.ws = null;
Wentao Shang0e291c82012-12-02 23:36:29 -080069
70 // Close NDN when WebSocket is closed
71 ndn.readyStatus = NDN.CLOSED;
72 ndn.onclose();
Wentao Shangaf25c6b2012-12-03 00:09:30 -080073 //console.log("NDN.onclose event fired.");
Jeff Thompson5b265a72012-11-12 01:13:08 -080074 }
Jeff Thompsonbe85be62012-12-13 22:32:01 -080075};
Jeff Thompson5b265a72012-11-12 01:13:08 -080076
Jeff Thompson75771cb2013-01-20 23:27:38 -080077/*
78 * Send the Uint8Array data.
79 */
80WebSocketTransport.prototype.send = function(data) {
Wentao Shangc0311e52012-12-03 10:38:23 -080081 if (this.ws != null) {
Jeff Thompson75771cb2013-01-20 23:27:38 -080082 // If we directly use data.buffer to feed ws.send(),
83 // WebSocket may end up sending a packet with 10000 bytes of data.
84 // That is, WebSocket will flush the entire buffer
85 // regardless of the offset of the Uint8Array. So we have to create
86 // a new Uint8Array buffer with just the right size and copy the
87 // content from binaryInterest to the new buffer.
88 // ---Wentao
89 var bytearray = new Uint8Array(data.length);
90 bytearray.set(data);
91 this.ws.send(bytearray.buffer);
Wentao Shangc0311e52012-12-03 10:38:23 -080092 if (LOG > 3) console.log('ws.send() returned.');
Wentao Shangc0311e52012-12-03 10:38:23 -080093 }
94 else
95 console.log('WebSocket connection is not established.');
Jeff Thompson5b265a72012-11-12 01:13:08 -080096}
97
Jeff Thompson75771cb2013-01-20 23:27:38 -080098WebSocketTransport.prototype.expressInterest = function(ndn, interest, closure) {
Jeff Thompsond771b122013-01-26 19:04:41 -080099 if (this.ws == null || this.connectedHost != ndn.host || this.connectedPort != ndn.port) {
100 var self = this;
101 this.connect(ndn, function() { self.expressInterestHelper(ndn, interest, closure); });
Jeff Thompson75771cb2013-01-20 23:27:38 -0800102 }
Jeff Thompsond771b122013-01-26 19:04:41 -0800103 else
104 this.expressInterestHelper(ndn, interest, closure);
105};
106
107WebSocketTransport.prototype.expressInterestHelper = function(ndn, interest, closure) {
Jeff Thompson75771cb2013-01-20 23:27:38 -0800108 //TODO: check local content store first
109 if (closure != null) {
110 var pitEntry = new PITEntry(interest, closure);
111 // TODO: This needs to be a single thread-safe transaction on a global object.
112 NDN.PITTable.push(pitEntry);
113 closure.pitEntry = pitEntry;
Jeff Thompson5b265a72012-11-12 01:13:08 -0800114 }
Jeff Thompson75771cb2013-01-20 23:27:38 -0800115
116 // Set interest timer
117 if (closure != null) {
118 pitEntry.timerID = setTimeout(function() {
119 if (LOG > 3) console.log("Interest time out.");
120
121 // Remove PIT entry from NDN.PITTable.
122 // TODO: Make this a thread-safe operation on the global PITTable.
123 var index = NDN.PITTable.indexOf(pitEntry);
124 //console.log(NDN.PITTable);
125 if (index >= 0)
126 NDN.PITTable.splice(index, 1);
127 //console.log(NDN.PITTable);
128 //console.log(pitEntry.interest.name.getName());
129
130 // Raise closure callback
131 closure.upcall(Closure.UPCALL_INTEREST_TIMED_OUT, new UpcallInfo(ndn, interest, 0, null));
132 }, interest.interestLifetime); // interestLifetime is in milliseconds.
133 //console.log(closure.timerID);
134 }
135
136 this.send(encodeToBinaryInterest(interest));
Jeff Thompsonbe85be62012-12-13 22:32:01 -0800137};