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 | bb9802d | 2013-01-20 23:54:18 -0800 | [diff] [blame] | 8 | this.elementReader = null; |
Jeff Thompson | c881b55 | 2012-12-14 01:29:12 -0800 | [diff] [blame] | 9 | this.defaultGetHostAndPort = NDN.makeShuffledGetHostAndPort |
| 10 | (["A.ws.ndn.ucla.edu", "B.ws.ndn.ucla.edu", "C.ws.ndn.ucla.edu", "D.ws.ndn.ucla.edu", |
| 11 | "E.ws.ndn.ucla.edu"], |
| 12 | 9696); |
Jeff Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 13 | }; |
| 14 | |
Jeff Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 15 | WebSocketTransport.prototype.connectWebSocket = function(ndn) { |
| 16 | if (this.ws != null) |
| 17 | delete this.ws; |
| 18 | |
| 19 | this.ws = new WebSocket('ws://' + ndn.host + ':' + ndn.port); |
Jeff Thompson | 3c26381 | 2012-12-01 17:20:28 -0800 | [diff] [blame] | 20 | if (LOG > 0) console.log('ws connection created.'); |
Jeff Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 21 | |
| 22 | this.ws.binaryType = "arraybuffer"; |
| 23 | |
Jeff Thompson | bb9802d | 2013-01-20 23:54:18 -0800 | [diff] [blame] | 24 | this.elementReader = new BinaryXmlElementReader(ndn); |
Jeff Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 25 | var self = this; |
| 26 | this.ws.onmessage = function(ev) { |
| 27 | var result = ev.data; |
| 28 | //console.log('RecvHandle called.'); |
| 29 | |
| 30 | if(result == null || result == undefined || result == "" ) { |
| 31 | console.log('INVALID ANSWER'); |
| 32 | } else if (result instanceof ArrayBuffer) { |
| 33 | var bytearray = new Uint8Array(result); |
| 34 | |
Jeff Thompson | 13c2e7b | 2012-12-01 17:33:30 -0800 | [diff] [blame] | 35 | if (LOG>3) console.log('BINARY RESPONSE IS ' + DataUtils.toHex(bytearray)); |
Jeff Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 36 | |
| 37 | try { |
Jeff Thompson | bb9802d | 2013-01-20 23:54:18 -0800 | [diff] [blame] | 38 | // Find the end of the binary XML element and call ndn.onReceivedElement. |
| 39 | self.elementReader.onReceivedData(bytearray); |
Jeff Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 40 | } catch (ex) { |
| 41 | console.log("NDN.ws.onmessage exception: " + ex); |
| 42 | return; |
| 43 | } |
Jeff Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 44 | } |
| 45 | } |
| 46 | |
| 47 | this.ws.onopen = function(ev) { |
Jeff Thompson | 3c26381 | 2012-12-01 17:20:28 -0800 | [diff] [blame] | 48 | if (LOG > 3) console.log(ev); |
| 49 | if (LOG > 3) console.log('ws.onopen: WebSocket connection opened.'); |
| 50 | if (LOG > 3) console.log('ws.onopen: ReadyState: ' + this.readyState); |
Jeff Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 51 | |
| 52 | // Fetch ccndid now |
Wentao Shang | e0d7f05 | 2013-01-05 16:37:02 -0800 | [diff] [blame] | 53 | var interest = new Interest(NDN.ccndIdFetcher); |
Jeff Thompson | 42806a1 | 2012-12-29 18:19:39 -0800 | [diff] [blame] | 54 | interest.interestLifetime = 4000; // milliseconds |
Jeff Thompson | 75771cb | 2013-01-20 23:27:38 -0800 | [diff] [blame] | 55 | this.send(encodeToBinaryInterest(interest)); |
Jeff Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 56 | } |
| 57 | |
| 58 | this.ws.onerror = function(ev) { |
| 59 | console.log('ws.onerror: ReadyState: ' + this.readyState); |
| 60 | console.log(ev); |
| 61 | console.log('ws.onerror: WebSocket error: ' + ev.data); |
| 62 | } |
| 63 | |
| 64 | this.ws.onclose = function(ev) { |
| 65 | console.log('ws.onclose: WebSocket connection closed.'); |
| 66 | self.ws = null; |
Wentao Shang | 0e291c8 | 2012-12-02 23:36:29 -0800 | [diff] [blame] | 67 | |
| 68 | // Close NDN when WebSocket is closed |
| 69 | ndn.readyStatus = NDN.CLOSED; |
| 70 | ndn.onclose(); |
Wentao Shang | af25c6b | 2012-12-03 00:09:30 -0800 | [diff] [blame] | 71 | //console.log("NDN.onclose event fired."); |
Jeff Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 72 | } |
Jeff Thompson | be85be6 | 2012-12-13 22:32:01 -0800 | [diff] [blame] | 73 | }; |
Jeff Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 74 | |
Jeff Thompson | 75771cb | 2013-01-20 23:27:38 -0800 | [diff] [blame] | 75 | /* |
| 76 | * Send the Uint8Array data. |
| 77 | */ |
| 78 | WebSocketTransport.prototype.send = function(data) { |
Wentao Shang | c0311e5 | 2012-12-03 10:38:23 -0800 | [diff] [blame] | 79 | if (this.ws != null) { |
Jeff Thompson | 75771cb | 2013-01-20 23:27:38 -0800 | [diff] [blame] | 80 | // If we directly use data.buffer to feed ws.send(), |
| 81 | // WebSocket may end up sending a packet with 10000 bytes of data. |
| 82 | // That is, WebSocket will flush the entire buffer |
| 83 | // regardless of the offset of the Uint8Array. So we have to create |
| 84 | // a new Uint8Array buffer with just the right size and copy the |
| 85 | // content from binaryInterest to the new buffer. |
| 86 | // ---Wentao |
| 87 | var bytearray = new Uint8Array(data.length); |
| 88 | bytearray.set(data); |
| 89 | this.ws.send(bytearray.buffer); |
Wentao Shang | c0311e5 | 2012-12-03 10:38:23 -0800 | [diff] [blame] | 90 | if (LOG > 3) console.log('ws.send() returned.'); |
Wentao Shang | c0311e5 | 2012-12-03 10:38:23 -0800 | [diff] [blame] | 91 | } |
| 92 | else |
| 93 | console.log('WebSocket connection is not established.'); |
Jeff Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 94 | } |
| 95 | |
Jeff Thompson | 75771cb | 2013-01-20 23:27:38 -0800 | [diff] [blame] | 96 | WebSocketTransport.prototype.expressInterest = function(ndn, interest, closure) { |
| 97 | if (ndn.readyStatus != NDN.OPENED) { |
| 98 | console.log('Connection is not established.'); |
| 99 | return; |
| 100 | } |
| 101 | |
| 102 | //TODO: check local content store first |
| 103 | if (closure != null) { |
| 104 | var pitEntry = new PITEntry(interest, closure); |
| 105 | // TODO: This needs to be a single thread-safe transaction on a global object. |
| 106 | NDN.PITTable.push(pitEntry); |
| 107 | closure.pitEntry = pitEntry; |
Jeff Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 108 | } |
Jeff Thompson | 75771cb | 2013-01-20 23:27:38 -0800 | [diff] [blame] | 109 | |
| 110 | // Set interest timer |
| 111 | if (closure != null) { |
| 112 | pitEntry.timerID = setTimeout(function() { |
| 113 | if (LOG > 3) console.log("Interest time out."); |
| 114 | |
| 115 | // Remove PIT entry from NDN.PITTable. |
| 116 | // TODO: Make this a thread-safe operation on the global PITTable. |
| 117 | var index = NDN.PITTable.indexOf(pitEntry); |
| 118 | //console.log(NDN.PITTable); |
| 119 | if (index >= 0) |
| 120 | NDN.PITTable.splice(index, 1); |
| 121 | //console.log(NDN.PITTable); |
| 122 | //console.log(pitEntry.interest.name.getName()); |
| 123 | |
| 124 | // Raise closure callback |
| 125 | closure.upcall(Closure.UPCALL_INTEREST_TIMED_OUT, new UpcallInfo(ndn, interest, 0, null)); |
| 126 | }, interest.interestLifetime); // interestLifetime is in milliseconds. |
| 127 | //console.log(closure.timerID); |
| 128 | } |
| 129 | |
| 130 | this.send(encodeToBinaryInterest(interest)); |
Jeff Thompson | be85be6 | 2012-12-13 22:32:01 -0800 | [diff] [blame] | 131 | }; |
Jeff Thompson | 5b265a7 | 2012-11-12 01:13:08 -0800 | [diff] [blame] | 132 | |