| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 'use strict'; | |
| 6 | |
| 7 /** @suppress {duplicate} */ | |
| 8 var remoting = remoting || {}; | |
| 9 | |
| 10 (function() { | |
| 11 | |
| 12 /** @type {Object<number, remoting.TcpSocket>} */ | |
| 13 var sockets = {}; | |
| 14 var receiveListenersAdded = false; | |
| 15 | |
| 16 function addReceiveListeners() { | |
| 17 if (receiveListenersAdded) { | |
| 18 return; | |
| 19 } | |
| 20 | |
| 21 receiveListenersAdded = true; | |
| 22 | |
| 23 chrome.sockets.tcp.onReceive.addListener(function( | |
| 24 /** chrome.sockets.tcp.ReceiveInfo */ info) { | |
| 25 var socket = sockets[info.socketId]; | |
| 26 if (socket === undefined) { | |
| 27 console.warn("Received data for unknown socket " + info.socketId); | |
| 28 return; | |
| 29 } | |
| 30 if (socket.receiveCallback_ === null) { | |
| 31 console.warn("Received data when socket was paused."); | |
| 32 return; | |
| 33 } | |
| 34 socket.receiveCallback_(info.data); | |
| 35 }); | |
| 36 | |
| 37 chrome.sockets.tcp.onReceiveError.addListener(function( | |
| 38 /** chrome.sockets.tcp.ReceiveErrorInfo */ info) { | |
| 39 var socket = sockets[info.socketId]; | |
| 40 if (socket === undefined) { | |
| 41 console.warn("Received error for unknown socket " + info.socketId); | |
| 42 return; | |
| 43 } | |
| 44 if (socket.receiveErrorCallback_ === null) { | |
| 45 console.warn("Recv() failed when socket was paused: " + info.resultCode); | |
| 46 return; | |
| 47 } | |
| 48 socket.receiveErrorCallback_(info.resultCode); | |
| 49 }); | |
| 50 } | |
| 51 | |
| 52 /** | |
| 53 * Wrapper for chrome.sockets.tcp API. | |
| 54 * | |
| 55 * @constructor | |
| 56 * @implements {base.Disposable} | |
| 57 */ | |
| 58 remoting.TcpSocket = function() { | |
| 59 /** @private */ | |
| 60 this.destroyed_ = false; | |
| 61 /** @private */ | |
| 62 this.socketId_ = -1; | |
| 63 /** @private {?function(ArrayBuffer):void} */ | |
| 64 this.receiveCallback_ = null; | |
| 65 /** @private {?function(number):void} */ | |
| 66 this.receiveErrorCallback_ = null; | |
| 67 | |
| 68 addReceiveListeners(); | |
| 69 }; | |
| 70 | |
| 71 /** | |
| 72 * Connects the socket to the specified host and port. | |
| 73 * | |
| 74 * @returns {Promise} Promise that's resolved when the socket is connected. | |
| 75 */ | |
| 76 remoting.TcpSocket.prototype.connect = function(/** string */ host, | |
| 77 /** number */ port) { | |
| 78 var that = this; | |
| 79 | |
| 80 return new Promise(function(resolve, reject) { | |
| 81 chrome.sockets.tcp.create({}, onCreated); | |
| 82 | |
| 83 | |
| 84 function onCreated(/** chrome.sockets.tcp.CreateInfo */ createInfo) { | |
| 85 // Check if the socket was destroyed. | |
| 86 if (that.destroyed_) { | |
| 87 chrome.sockets.tcp.close(createInfo.socketId); | |
| 88 return; | |
| 89 } | |
| 90 | |
| 91 that.socketId_ = createInfo.socketId; | |
| 92 sockets[that.socketId_] = that; | |
| 93 | |
| 94 // Pause the socket so that we start receiving only after startReceiving() | |
| 95 // is called. | |
| 96 chrome.sockets.tcp.setPaused(that.socketId_, true); | |
| 97 | |
| 98 chrome.sockets.tcp.connect(that.socketId_, host, port, onConnected); | |
| 99 } | |
| 100 | |
| 101 function onConnected(/** number */ result) { | |
| 102 if (that.destroyed_) { | |
| 103 return; | |
| 104 } | |
| 105 | |
| 106 if (result < 0) { | |
| 107 reject(result); | |
| 108 } else { | |
| 109 resolve(0); | |
| 110 } | |
| 111 } | |
| 112 }); | |
| 113 }; | |
| 114 | |
| 115 remoting.TcpSocket.prototype.dispose = function() { | |
| 116 if (this.socketId_ != -1) { | |
| 117 chrome.sockets.tcp.close(this.socketId_); | |
| 118 delete sockets[this.socketId_]; | |
| 119 this.socketId_ = -1; | |
| 120 } | |
| 121 this.destroyed_ = true; | |
| 122 this.receiveCallback_ = null; | |
| 123 }; | |
| 124 | |
| 125 /** | |
| 126 * Starts receiving data on the socket. Calls receiveCallback when new data is | |
| 127 * received or receiveErrorCallback when recv() returns an error. | |
| 128 */ | |
| 129 remoting.TcpSocket.prototype.startReceiving = function( | |
| 130 /** ?function(ArrayBuffer):void */ receiveCallback, | |
| 131 /** ?function(number):void */ receiveErrorCallback) { | |
| 132 base.debug.assert(this.receiveCallback_ == null); | |
| 133 this.receiveCallback_ = receiveCallback; | |
| 134 this.receiveErrorCallback_ = receiveErrorCallback; | |
| 135 chrome.sockets.tcp.setPaused(this.socketId_, false); | |
| 136 }; | |
| 137 | |
| 138 /** | |
| 139 * Sends |data|. | |
| 140 * | |
| 141 * @returns {Promise} | |
| 142 */ | |
| 143 remoting.TcpSocket.prototype.send = function(/** ArrayBuffer */ data) { | |
| 144 var that = this; | |
| 145 | |
| 146 return new Promise(function(resolve, reject) { | |
| 147 chrome.sockets.tcp.send(that.socketId_, data, function(sendInfo) { | |
| 148 if (sendInfo.resultCode < 0) { | |
| 149 reject(sendInfo.resultCode); | |
| 150 } else { | |
| 151 resolve(sendInfo.bytesSent); | |
| 152 } | |
| 153 }); | |
| 154 }); | |
| 155 }; | |
| 156 | |
| 157 /** | |
| 158 * Starts TLS on the socket. Once TLS is negotiated the caller will need to call | |
| 159 * startReceiving() to start receiving data, even if startReceiving() was called | |
| 160 * before. | |
| 161 * | |
| 162 * @returns {Promise} | |
| 163 */ | |
| 164 remoting.TcpSocket.prototype.startTls = function() { | |
| 165 var that = this; | |
| 166 | |
| 167 return new Promise(function(resolve, reject) { | |
| 168 function doStartTls() { | |
| 169 chrome.sockets.tcp.secure(that.socketId_, {}, function(result) { | |
| 170 if (result < 0) { | |
| 171 reject(result); | |
| 172 } else { | |
| 173 resolve(0); | |
| 174 } | |
| 175 }); | |
| 176 } | |
| 177 | |
| 178 if (!that.receiveCallback_) { | |
| 179 // Socket is already paused. | |
| 180 doStartTls(); | |
| 181 } else { | |
| 182 // Socket must be paused before staring TLS. This won't work correctly | |
| 183 // until crbug.com/403076 is fixed. Log a warning and try anyway. | |
| 184 console.warn( | |
| 185 "remoting.TcpSocket.secure() was called after some data was " + | |
| 186 "received on the socket. This won't work properly until " + | |
| 187 "crbug.com/403076 is fixed."); | |
| 188 chrome.sockets.tcp.setPaused(that.socketId_, true, function() { | |
| 189 if (that.destroyed_) { | |
| 190 return; | |
| 191 } | |
| 192 that.receiveCallback_ = null; | |
| 193 that.receiveErrorCallback_ = null; | |
| 194 doStartTls(); | |
| 195 }); | |
| 196 } | |
| 197 }); | |
| 198 }; | |
| 199 | |
| 200 })(); | |
| OLD | NEW |