Wentao Shang | c0311e5 | 2012-12-03 10:38:23 -0800 | [diff] [blame] | 1 | /** |
Jeff Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 2 | * @author: Wentao Shang |
| 3 | * See COPYING for copyright and distribution information. |
Jeff Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 4 | */ |
| 5 | |
| 6 | var WebSocketTransport = function WebSocketTransport() { |
| 7 | this.ws = null; |
Jeff Thompson | d771b12 | 2013-01-26 19:04:41 -0800 | [diff] [blame^] | 8 | this.connectedHost = null; |
| 9 | this.connectedPort = null; |
Jeff Thompson | bb9802d | 2013-01-20 23:54:18 -0800 | [diff] [blame] | 10 | this.elementReader = null; |
Jeff Thompson | c881b55 | 2012-12-14 01:29:12 -0800 | [diff] [blame] | 11 | 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 Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 15 | }; |
| 16 | |
Jeff Thompson | d771b12 | 2013-01-26 19:04:41 -0800 | [diff] [blame^] | 17 | WebSocketTransport.prototype.connect = function(ndn, onopenCallback) { |
Jeff Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 18 | if (this.ws != null) |
| 19 | delete this.ws; |
| 20 | |
| 21 | this.ws = new WebSocket('ws://' + ndn.host + ':' + ndn.port); |
Jeff Thompson | 3c26381 | 2012-12-01 17:20:28 -0800 | [diff] [blame] | 22 | if (LOG > 0) console.log('ws connection created.'); |
Jeff Thompson | d771b12 | 2013-01-26 19:04:41 -0800 | [diff] [blame^] | 23 | this.connectedHost = ndn.host; |
| 24 | this.connectedPort = ndn.port; |
Jeff Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 25 | |
| 26 | this.ws.binaryType = "arraybuffer"; |
| 27 | |
Jeff Thompson | bb9802d | 2013-01-20 23:54:18 -0800 | [diff] [blame] | 28 | this.elementReader = new BinaryXmlElementReader(ndn); |
Jeff Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 29 | 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 Thompson | 13c2e7b | 2012-12-01 17:33:30 -0800 | [diff] [blame] | 39 | if (LOG>3) console.log('BINARY RESPONSE IS ' + DataUtils.toHex(bytearray)); |
Jeff Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 40 | |
| 41 | try { |
Jeff Thompson | bb9802d | 2013-01-20 23:54:18 -0800 | [diff] [blame] | 42 | // Find the end of the binary XML element and call ndn.onReceivedElement. |
| 43 | self.elementReader.onReceivedData(bytearray); |
Jeff Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 44 | } catch (ex) { |
| 45 | console.log("NDN.ws.onmessage exception: " + ex); |
| 46 | return; |
| 47 | } |
Jeff Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 48 | } |
| 49 | } |
| 50 | |
| 51 | this.ws.onopen = function(ev) { |
Jeff Thompson | 3c26381 | 2012-12-01 17:20:28 -0800 | [diff] [blame] | 52 | 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 Thompson | d771b12 | 2013-01-26 19:04:41 -0800 | [diff] [blame^] | 55 | // NDN.registerPrefix will fetch the ccndid when needed. |
| 56 | |
| 57 | onopenCallback(); |
Jeff Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 58 | } |
| 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 Shang | 0e291c8 | 2012-12-02 23:36:29 -0800 | [diff] [blame] | 69 | |
| 70 | // Close NDN when WebSocket is closed |
| 71 | ndn.readyStatus = NDN.CLOSED; |
| 72 | ndn.onclose(); |
Wentao Shang | af25c6b | 2012-12-03 00:09:30 -0800 | [diff] [blame] | 73 | //console.log("NDN.onclose event fired."); |
Jeff Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 74 | } |
Jeff Thompson | be85be6 | 2012-12-13 22:32:01 -0800 | [diff] [blame] | 75 | }; |
Jeff Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 76 | |
Jeff Thompson | 75771cb | 2013-01-20 23:27:38 -0800 | [diff] [blame] | 77 | /* |
| 78 | * Send the Uint8Array data. |
| 79 | */ |
| 80 | WebSocketTransport.prototype.send = function(data) { |
Wentao Shang | c0311e5 | 2012-12-03 10:38:23 -0800 | [diff] [blame] | 81 | if (this.ws != null) { |
Jeff Thompson | 75771cb | 2013-01-20 23:27:38 -0800 | [diff] [blame] | 82 | // 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 Shang | c0311e5 | 2012-12-03 10:38:23 -0800 | [diff] [blame] | 92 | if (LOG > 3) console.log('ws.send() returned.'); |
Wentao Shang | c0311e5 | 2012-12-03 10:38:23 -0800 | [diff] [blame] | 93 | } |
| 94 | else |
| 95 | console.log('WebSocket connection is not established.'); |
Jeff Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 96 | } |
| 97 | |
Jeff Thompson | 75771cb | 2013-01-20 23:27:38 -0800 | [diff] [blame] | 98 | WebSocketTransport.prototype.expressInterest = function(ndn, interest, closure) { |
Jeff Thompson | d771b12 | 2013-01-26 19:04:41 -0800 | [diff] [blame^] | 99 | 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 Thompson | 75771cb | 2013-01-20 23:27:38 -0800 | [diff] [blame] | 102 | } |
Jeff Thompson | d771b12 | 2013-01-26 19:04:41 -0800 | [diff] [blame^] | 103 | else |
| 104 | this.expressInterestHelper(ndn, interest, closure); |
| 105 | }; |
| 106 | |
| 107 | WebSocketTransport.prototype.expressInterestHelper = function(ndn, interest, closure) { |
Jeff Thompson | 75771cb | 2013-01-20 23:27:38 -0800 | [diff] [blame] | 108 | //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 Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 114 | } |
Jeff Thompson | 75771cb | 2013-01-20 23:27:38 -0800 | [diff] [blame] | 115 | |
| 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 Thompson | be85be6 | 2012-12-13 22:32:01 -0800 | [diff] [blame] | 137 | }; |