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 |