| OLD | NEW |
| 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * @constructor | 6 * @constructor |
| 7 * @extends {InspectorBackendClass.Connection} | 7 * @implements {InspectorBackendClass.Connection} |
| 8 * @param {!InspectorBackendClass.Connection.Params} params |
| 8 */ | 9 */ |
| 9 WebInspector.MainConnection = function() | 10 WebInspector.MainConnection = function(params) |
| 10 { | 11 { |
| 11 InspectorBackendClass.Connection.call(this); | 12 this._onMessage = params.onMessage; |
| 12 InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Event
s.DispatchMessage, this._dispatchMessage, this); | 13 this._onDisconnect = params.onDisconnect; |
| 13 InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Event
s.DispatchMessageChunk, this._dispatchMessageChunk, this); | 14 this._disconnected = false; |
| 14 InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Event
s.EvaluateForTestInFrontend, this._evaluateForTestInFrontend, this); | 15 this._eventListeners = [ |
| 15 }; | 16 InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.E
vents.DispatchMessage, this._dispatchMessage, this), |
| 17 InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.E
vents.DispatchMessageChunk, this._dispatchMessageChunk, this), |
| 18 InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.E
vents.EvaluateForTestInFrontend, this._evaluateForTestInFrontend, this), |
| 19 ]; |
| 20 } |
| 16 | 21 |
| 17 WebInspector.MainConnection.prototype = { | 22 WebInspector.MainConnection.prototype = { |
| 23 |
| 18 /** | 24 /** |
| 19 * @override | 25 * @override |
| 20 * @param {!Object} messageObject | 26 * @param {string} message |
| 21 */ | 27 */ |
| 22 sendMessage: function(messageObject) | 28 sendMessage: function(message) |
| 23 { | 29 { |
| 24 var message = JSON.stringify(messageObject); | 30 if (!this._disconnected) |
| 25 InspectorFrontendHost.sendMessageToBackend(message); | 31 InspectorFrontendHost.sendMessageToBackend(message); |
| 26 }, | 32 }, |
| 27 | 33 |
| 28 /** | 34 /** |
| 29 * @param {!WebInspector.Event} event | 35 * @param {!WebInspector.Event} event |
| 30 */ | 36 */ |
| 31 _dispatchMessage: function(event) | 37 _dispatchMessage: function(event) |
| 32 { | 38 { |
| 33 this.dispatch(/** @type {string} */ (event.data)); | 39 this._onMessage.call(null, /** @type {string} */ (event.data)); |
| 34 }, | 40 }, |
| 35 | 41 |
| 36 /** | 42 /** |
| 37 * @param {!WebInspector.Event} event | 43 * @param {!WebInspector.Event} event |
| 38 */ | 44 */ |
| 39 _dispatchMessageChunk: function(event) | 45 _dispatchMessageChunk: function(event) |
| 40 { | 46 { |
| 41 var messageChunk = /** @type {string} */ (event.data["messageChunk"]); | 47 var messageChunk = /** @type {string} */ (event.data["messageChunk"]); |
| 42 var messageSize = /** @type {number} */ (event.data["messageSize"]); | 48 var messageSize = /** @type {number} */ (event.data["messageSize"]); |
| 43 if (messageSize) { | 49 if (messageSize) { |
| 44 this._messageBuffer = ""; | 50 this._messageBuffer = ""; |
| 45 this._messageSize = messageSize; | 51 this._messageSize = messageSize; |
| 46 } | 52 } |
| 47 this._messageBuffer += messageChunk; | 53 this._messageBuffer += messageChunk; |
| 48 if (this._messageBuffer.length === this._messageSize) { | 54 if (this._messageBuffer.length === this._messageSize) { |
| 49 this.dispatch(this._messageBuffer); | 55 this._onMessage.call(null, this._messageBuffer); |
| 50 this._messageBuffer = ""; | 56 this._messageBuffer = ""; |
| 51 this._messageSize = 0; | 57 this._messageSize = 0; |
| 52 } | 58 } |
| 53 }, | 59 }, |
| 54 | 60 |
| 55 /** | 61 /** |
| 56 * @param {!WebInspector.Event} event | 62 * @param {!WebInspector.Event} event |
| 57 */ | 63 */ |
| 58 _evaluateForTestInFrontend: function(event) | 64 _evaluateForTestInFrontend: function(event) |
| 59 { | 65 { |
| 60 if (!InspectorFrontendHost.isUnderTest()) | 66 if (!InspectorFrontendHost.isUnderTest()) |
| 61 return; | 67 return; |
| 62 | 68 |
| 63 var callId = /** @type {number} */ (event.data["callId"]); | 69 var callId = /** @type {number} */ (event.data["callId"]); |
| 64 var script = /** @type {number} */ (event.data["script"]); | 70 var script = /** @type {number} */ (event.data["script"]); |
| 65 | 71 |
| 66 /** | 72 /** |
| 67 * @suppressGlobalPropertiesCheck | 73 * @suppressGlobalPropertiesCheck |
| 68 */ | 74 */ |
| 69 function invokeMethod() | 75 function invokeMethod() |
| 70 { | 76 { |
| 71 try { | 77 try { |
| 72 script = script + "//# sourceURL=evaluateInWebInspector" + callI
d + ".js"; | 78 script = script + "//# sourceURL=evaluateInWebInspector" + callI
d + ".js"; |
| 73 window.eval(script); | 79 window.eval(script); |
| 74 } catch (e) { | 80 } catch (e) { |
| 75 console.error(e.stack); | 81 console.error(e.stack); |
| 76 } | 82 } |
| 77 } | 83 } |
| 78 | 84 |
| 79 this.deprecatedRunAfterPendingDispatches(invokeMethod); | 85 InspectorBackendClass.deprecatedRunAfterPendingDispatches(invokeMethod); |
| 80 }, | 86 }, |
| 81 | 87 |
| 82 /** | 88 /** |
| 83 * @override | 89 * @override |
| 90 * @return {!Promise} |
| 84 */ | 91 */ |
| 85 forceClose: function() | 92 disconnect: function() |
| 86 { | 93 { |
| 87 InspectorFrontendHost.events.removeEventListener(InspectorFrontendHostAP
I.Events.DispatchMessage, this._dispatchMessage, this); | 94 var onDisconnect = this._onDisconnect; |
| 88 InspectorFrontendHost.events.removeEventListener(InspectorFrontendHostAP
I.Events.DispatchMessageChunk, this._dispatchMessageChunk, this); | 95 WebInspector.EventTarget.removeEventListeners(this._eventListeners); |
| 89 InspectorFrontendHost.events.removeEventListener(InspectorFrontendHostAP
I.Events.EvaluateForTestInFrontend, this._evaluateForTestInFrontend, this); | 96 this._onDisconnect = null; |
| 97 this._onMessage = null; |
| 98 this._disconnected = true; |
| 99 |
| 100 var fulfill; |
| 101 var promise = new Promise(f => fulfill = f); |
| 102 InspectorFrontendHost.reattach(() => { |
| 103 onDisconnect.call(null, "force disconnect"); |
| 104 fulfill(); |
| 105 }); |
| 106 return promise; |
| 90 }, | 107 }, |
| 91 | |
| 92 __proto__: InspectorBackendClass.Connection.prototype | |
| 93 }; | 108 }; |
| 94 | 109 |
| 95 /** | 110 /** |
| 96 * @constructor | 111 * @constructor |
| 97 * @extends {InspectorBackendClass.Connection} | 112 * @implements {InspectorBackendClass.Connection} |
| 98 * @param {string} url | 113 * @param {string} url |
| 99 * @param {function(!InspectorBackendClass.Connection)} onConnectionReady | 114 * @param {!InspectorBackendClass.Connection.Params} params |
| 100 */ | 115 */ |
| 101 WebInspector.WebSocketConnection = function(url, onConnectionReady) | 116 WebInspector.WebSocketConnection = function(url, params) |
| 102 { | 117 { |
| 103 InspectorBackendClass.Connection.call(this); | |
| 104 this._socket = new WebSocket(url); | 118 this._socket = new WebSocket(url); |
| 105 this._socket.onmessage = this._onMessage.bind(this); | |
| 106 this._socket.onerror = this._onError.bind(this); | 119 this._socket.onerror = this._onError.bind(this); |
| 107 this._socket.onopen = onConnectionReady.bind(null, this); | 120 this._socket.onopen = this._onOpen.bind(this); |
| 108 this._socket.onclose = this.connectionClosed.bind(this, "websocket_closed"); | 121 this._socket.onmessage = (messageEvent) => params.onMessage.call(null, /** @
type {string} */ (messageEvent.data)); |
| 109 }; | 122 this._onDisconnect = params.onDisconnect; |
| 123 this._socket.onclose = params.onDisconnect.bind(null, "websocket closed"); |
| 110 | 124 |
| 111 /** | 125 this._connected = false; |
| 112 * @param {string} url | 126 this._messages = []; |
| 113 * @return {!Promise<!InspectorBackendClass.Connection>} | |
| 114 */ | |
| 115 WebInspector.WebSocketConnection.Create = function(url) | |
| 116 { | |
| 117 var fulfill; | |
| 118 var result = new Promise(resolve => fulfill = resolve); | |
| 119 new WebInspector.WebSocketConnection(url, fulfill); | |
| 120 return result; | |
| 121 }; | 127 }; |
| 122 | 128 |
| 123 WebInspector.WebSocketConnection.prototype = { | 129 WebInspector.WebSocketConnection.prototype = { |
| 124 | 130 _onError: function() |
| 125 /** | |
| 126 * @param {!MessageEvent} message | |
| 127 */ | |
| 128 _onMessage: function(message) | |
| 129 { | 131 { |
| 130 var data = /** @type {string} */ (message.data); | 132 // This is called if error occurred while connecting. |
| 131 this.dispatch(data); | 133 this._onDisconnect.call(null, "connection failed"); |
| 134 this._close(); |
| 132 }, | 135 }, |
| 133 | 136 |
| 134 /** | 137 _onOpen: function() |
| 135 * @param {!Event} error | |
| 136 */ | |
| 137 _onError: function(error) | |
| 138 { | 138 { |
| 139 console.error(error); | 139 this._socket.onerror = console.error; |
| 140 this._connected = true; |
| 141 for (var message of this._messages) |
| 142 this._socket.send(message); |
| 143 this._messages = []; |
| 144 }, |
| 145 |
| 146 _close: function() |
| 147 { |
| 148 this._socket.onerror = null; |
| 149 this._socket.onopen = null; |
| 150 this._socket.onclose = null; |
| 151 this._socket.onmessage = null; |
| 152 this._socket.close(); |
| 153 this._socket = null; |
| 140 }, | 154 }, |
| 141 | 155 |
| 142 /** | 156 /** |
| 143 * @override | 157 * @override |
| 158 * @param {string} message |
| 144 */ | 159 */ |
| 145 forceClose: function() | 160 sendMessage: function(message) |
| 146 { | 161 { |
| 147 this._socket.close(); | 162 if (this._connected) |
| 163 this._socket.send(message); |
| 164 else |
| 165 this._messages.push(message); |
| 148 }, | 166 }, |
| 149 | 167 |
| 150 /** | 168 /** |
| 151 * @override | 169 * @override |
| 152 * @param {!Object} messageObject | 170 * @return {!Promise} |
| 153 */ | 171 */ |
| 154 sendMessage: function(messageObject) | 172 disconnect: function() |
| 155 { | 173 { |
| 156 var message = JSON.stringify(messageObject); | 174 this._onDisconnect.call(null, "force disconnect"); |
| 157 this._socket.send(message); | 175 this._close(); |
| 158 }, | 176 return Promise.resolve(); |
| 159 | 177 } |
| 160 __proto__: InspectorBackendClass.Connection.prototype | |
| 161 }; | 178 }; |
| 162 | 179 |
| 163 /** | 180 /** |
| 164 * @constructor | 181 * @constructor |
| 165 * @extends {InspectorBackendClass.Connection} | 182 * @implements {InspectorBackendClass.Connection} |
| 183 * @param {!InspectorBackendClass.Connection.Params} params |
| 166 */ | 184 */ |
| 167 WebInspector.StubConnection = function() | 185 WebInspector.StubConnection = function(params) |
| 168 { | 186 { |
| 169 InspectorBackendClass.Connection.call(this); | 187 this._onMessage = params.onMessage; |
| 188 this._onDisconnect = params.onDisconnect; |
| 170 }; | 189 }; |
| 171 | 190 |
| 172 WebInspector.StubConnection.prototype = { | 191 WebInspector.StubConnection.prototype = { |
| 173 /** | 192 /** |
| 174 * @override | 193 * @override |
| 175 * @param {!Object} messageObject | 194 * @param {string} message |
| 176 */ | 195 */ |
| 177 sendMessage: function(messageObject) | 196 sendMessage: function(message) |
| 178 { | 197 { |
| 179 setTimeout(this._respondWithError.bind(this, messageObject), 0); | 198 setTimeout(this._respondWithError.bind(this, message), 0); |
| 180 }, | 199 }, |
| 181 | 200 |
| 182 /** | 201 /** |
| 183 * @param {!Object} messageObject | |
| 184 */ | |
| 185 _respondWithError: function(messageObject) | |
| 186 { | |
| 187 var error = { message: "This is a stub connection, can't dispatch messag
e.", code: InspectorBackendClass.DevToolsStubErrorCode, data: messageObject }; | |
| 188 this.dispatch({ id: messageObject.id, error: error }); | |
| 189 }, | |
| 190 | |
| 191 __proto__: InspectorBackendClass.Connection.prototype | |
| 192 }; | |
| 193 | |
| 194 | |
| 195 /** | |
| 196 * @constructor | |
| 197 * @param {function(string)} dispatchCallback | |
| 198 * @param {function()} yieldCallback | |
| 199 */ | |
| 200 WebInspector.RawProtocolConnection = function(dispatchCallback, yieldCallback) | |
| 201 { | |
| 202 InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Event
s.DispatchMessage, this._dispatchMessage, this); | |
| 203 InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Event
s.DispatchMessageChunk, this._dispatchMessageChunk, this); | |
| 204 this._dispatchCallback = dispatchCallback; | |
| 205 this._yieldCallback = yieldCallback; | |
| 206 this._isClosed = false; | |
| 207 }; | |
| 208 | |
| 209 WebInspector.RawProtocolConnection.prototype = { | |
| 210 /** | |
| 211 * @param {string} message | 202 * @param {string} message |
| 212 */ | 203 */ |
| 213 send: function(message) | 204 _respondWithError: function(message) |
| 214 { | 205 { |
| 215 if (this._isClosed) | 206 var messageObject = JSON.parse(message); |
| 216 return; | 207 var error = { message: "This is a stub connection, can't dispatch messag
e.", code: InspectorBackendClass.DevToolsStubErrorCode, data: messageObject }; |
| 217 InspectorFrontendHost.sendMessageToBackend(message); | 208 this._onMessage.call(null, { id: messageObject.id, error: error }); |
| 218 }, | 209 }, |
| 219 | 210 |
| 220 /** | 211 /** |
| 221 * @param {!WebInspector.Event} event | 212 * @override |
| 213 * @return {!Promise} |
| 222 */ | 214 */ |
| 223 _dispatchMessage: function(event) | 215 disconnect: function() |
| 224 { | 216 { |
| 225 this._dispatchCallback(/** @type {string} */ (event.data)); | 217 this._onDisconnect.call(null, "force disconnect"); |
| 218 this._onDisconnect = null; |
| 219 this._onMessage = null; |
| 220 return Promise.resolve(); |
| 226 }, | 221 }, |
| 227 | |
| 228 /** | |
| 229 * @param {!WebInspector.Event} event | |
| 230 */ | |
| 231 _dispatchMessageChunk: function(event) | |
| 232 { | |
| 233 var messageChunk = /** @type {string} */ (event.data["messageChunk"]); | |
| 234 var messageSize = /** @type {number} */ (event.data["messageSize"]); | |
| 235 if (messageSize) { | |
| 236 this._messageBuffer = ""; | |
| 237 this._messageSize = messageSize; | |
| 238 } | |
| 239 this._messageBuffer += messageChunk; | |
| 240 if (this._messageBuffer.length === this._messageSize) { | |
| 241 this._dispatchCallback(this._messageBuffer); | |
| 242 this._messageBuffer = ""; | |
| 243 this._messageSize = 0; | |
| 244 } | |
| 245 }, | |
| 246 | |
| 247 yieldConnection: function() | |
| 248 { | |
| 249 InspectorFrontendHost.events.removeEventListener(InspectorFrontendHostAP
I.Events.DispatchMessage, this._dispatchMessage, this); | |
| 250 InspectorFrontendHost.events.removeEventListener(InspectorFrontendHostAP
I.Events.DispatchMessageChunk, this._dispatchMessageChunk, this); | |
| 251 this._isClosed = true; | |
| 252 delete this._dispatchCallback; | |
| 253 this._yieldCallback(); | |
| 254 } | |
| 255 }; | 222 }; |
| OLD | NEW |