From c377f2a1633af590b03dca272b7b4b4228ce9d4e Mon Sep 17 00:00:00 2001 From: Walter Luh Date: Thu, 25 Feb 2016 18:14:55 -0800 Subject: [PATCH] Add message channel to packager for sending commands to bridge (2/N) Reviewed By: frantic Differential Revision: D2957599 fb-gh-sync-id: 0d3f39bb5757c7af8ee6d178f4839af81928b8de shipit-source-id: 0d3f39bb5757c7af8ee6d178f4839af81928b8de --- local-cli/server/runServer.js | 4 ++ local-cli/server/util/messageSocket.js | 88 ++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 local-cli/server/util/messageSocket.js diff --git a/local-cli/server/runServer.js b/local-cli/server/runServer.js index 3f5f33aee..57c0be9d2 100644 --- a/local-cli/server/runServer.js +++ b/local-cli/server/runServer.js @@ -15,6 +15,7 @@ const getDevToolsMiddleware = require('./middleware/getDevToolsMiddleware'); const http = require('http'); const isAbsolutePath = require('absolute-path'); const loadRawBodyMiddleware = require('./middleware/loadRawBodyMiddleware'); +const messageSocket = require('./util/messageSocket.js'); const openStackFrameInEditorMiddleware = require('./middleware/openStackFrameInEditorMiddleware'); const path = require('path'); const ReactPackager = require('../../packager/react-packager'); @@ -24,11 +25,13 @@ const webSocketProxy = require('./util/webSocketProxy.js'); function runServer(args, config, readyCallback) { var wsProxy = null; + var ms = null; const packagerServer = getPackagerServer(args, config); const app = connect() .use(loadRawBodyMiddleware) .use(connect.compress()) .use(getDevToolsMiddleware(args, () => wsProxy && wsProxy.isChromeConnected())) + .use(getDevToolsMiddleware(args, () => ms && ms.isChromeConnected())) .use(openStackFrameInEditorMiddleware) .use(statusPageMiddleware) .use(systraceProfileMiddleware) @@ -51,6 +54,7 @@ function runServer(args, config, readyCallback) { }); wsProxy = webSocketProxy.attachToServer(serverInstance, '/debugger-proxy'); + ms = messageSocket.attachToServer(serverInstance, '/message'); webSocketProxy.attachToServer(serverInstance, '/devtools'); readyCallback(); } diff --git a/local-cli/server/util/messageSocket.js b/local-cli/server/util/messageSocket.js new file mode 100644 index 000000000..3c56aa054 --- /dev/null +++ b/local-cli/server/util/messageSocket.js @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +'use strict'; + + +function attachToServer(server, path) { + var WebSocketServer = require('ws').Server; + var wss = new WebSocketServer({ + server: server, + path: path + }); + var interfaceSocket, shellSocket; + + function send(dest, message) { + if (!dest) { + return; + } + + try { + dest.send(message); + } catch(e) { + console.warn(e); + // Sometimes this call throws 'not opened' + } + } + + wss.on('connection', function(ws) { + const {url} = ws.upgradeReq; + + if (url.indexOf('role=interface') > -1) { + if (interfaceSocket) { + ws.close(1011, 'Another debugger is already connected'); + return; + } + interfaceSocket = ws; + interfaceSocket.onerror = + interfaceSocket.onclose = () => { + interfaceSocket = null; + // if (shellSocket) { + // shellSocket.close(1011, 'Interface was disconnected'); + // } + }; + + interfaceSocket.onmessage = ({data}) => { + send(shellSocket, data) + }; + } else if (url.indexOf('role=shell') > -1) { + if (shellSocket) { + shellSocket.onerror = shellSocket.onclose = shellSocket.onmessage = null; + shellSocket.close(1011, 'Another client connected'); + } + shellSocket = ws; + shellSocket.onerror = + shellSocket.onclose = () => { + shellSocket = null; + send(interfaceSocket, JSON.stringify({method: '$disconnected'})); + }; + shellSocket.onmessage = ({data}) => send(interfaceSocket, data); + + // console.log('CLIENT ----'); + // if (doIt) { + // console.log('> sending: %s', str); + // send(shellSocket, str); + // console.log('< sending'); + // } + + } else { + ws.close(1011, 'Missing role param'); + } + }); + + return { + server: wss, + isChromeConnected: function() { + return !!interfaceSocket; + } + }; +} + +module.exports = { + attachToServer: attachToServer +};