UNPKG

@smartface/emulator-dispatcher

Version:

Handles Emulator Dispatcher Part of SmartfaceCloud

233 lines (206 loc) 7.22 kB
const Workspace = require('../workspace/workspace'); const uuid = require('uuid'); const MessageFactory = require('../common/MessageFactory'); const debugSession = require('../debug/debugsession.js'); const LogToConsole = require('../common/LogToConsole'); const sendResetTimeout = require('../common/sendResetTimeout'); const CONSTANTS = require('../constants'); function ControlService() { const UI = 'UI'; const DEVICE = 'device'; const MESSAGE = 'message'; const FILE_TRANSFER = 'file-transfer'; const DEBUGGER = 'debugger'; const ALL = '*'; const waitForSync = true; const messageFactory = new MessageFactory(); let workspace = null; let request; const callbackList = {}; const self = this; let log; let debug; this.request = null; this.deviceInfo = null; this.init = function (requestService, opts) { opts = opts || {}; const logger = new LogToConsole(opts.logToConsole, '[CONTROL]'); log = logger.log; debug = logger.debug; request = requestService; getWorkspaceOptions(); }; this.handleMessage = function (from, message, connectedObject) { log('Handle message from', from); if (callbackList[message.id]) { callbackList[message.id](null, message); } else { if (message.event) { if (message.event === 'fileTransferCompleted') { self.start('Project'); } else if (message.event === 'switchedProject') { self.init(request); } } if (message.command) { if (message.command === 'pingDevice') { self.ping(); } else if (message.command === 'start project') { if (message.data.debugSupported) { var randomID = uuid.v4(); var handledRespone = false; if (global.shared.uiCommandEventEmiter) { global.shared.uiCommandEventEmiter.once('resume project', sendDebugMessages); global.shared.uiCommandEventEmiter.once('resumeFromSync', sendResumeFromSync); } const messageStartWithDebug = messageFactory.createMessage('start project', { responseID: randomID, debugger: message.data.debugger }); sendRequest(UI, null, messageStartWithDebug); var timeoutID = setTimeout(() => { sendDebugMessages({ data: {} }); }, 30000); } else { sendStartDebug(); } } else if (message.command === 'getIndex') { self.deviceInfo = message.data; global.shared.allDeviceInfos[self.deviceInfo.deviceID] = self.deviceInfo; sendRequest(ALL, null, { event: 'deviceInfo', deviceInfo: self.deviceInfo }); if (workspace == null) { getWorkspaceOptions((err, received) => { if (err) throw err; self.sendIndex(); }); } else { self.sendIndex(); } } else if (message.command === 'cancelTransfer') { const messageToDevice = {}; messageToDevice.errors = []; messageToDevice.warnings = []; messageToDevice.errors.push(message.data.errorMessage); sendRequest(DEVICE, null, messageFactory.createMessage( 'cancelTransfer', messageToDevice )); } else if (message.command === 'stop project') { const responseMessage = messageFactory.createMessage('stop project', { responseID: uuid.v4() }); sendRequest(UI, null, responseMessage); } else if (message.command === 'resetTimeout') { sendRequest(DEVICE, null, messageFactory.createMessage(message.command)); } } } function sendStartDebug(isDebugging) { const { allUIWebsockets } = global.shared; let messageResponse; if (connectedObject && !allUIWebsockets[connectedObject.browserGuid]) { isDebugging = false; } messageResponse = messageFactory.createMessage('resume project', { debug: !!isDebugging, waitForSync }); messageResponse.id = message.id; sendRequest(DEVICE, null, messageResponse); log('Sending resume project to DEVICE with isDebugging:', !!isDebugging); } function sendDebugMessages(message) { clearTimeout(timeoutID); if (handledRespone) return; handledRespone = true; let isDebugging = (randomID === message.data.responseID && message.data.isDebugging); if (isDebugging) { isDebugging = !!debugSession.createNewSession(connectedObject, { logToConsole: true }); if (isDebugging) { const messageAttach = messageFactory.createMessage('attach', {}); log('Attach issued'); sendRequest(UI, null, messageAttach); } } sendStartDebug(isDebugging); } function sendResumeFromSync() { const messageResumeFromSync = messageFactory.createMessage('resumeFromSync', {}); sendRequest(DEVICE, null, messageResumeFromSync); } }; function getWorkspaceOptions(callback) { log('Received workspace options'); const received = { path: CONSTANTS.WORKSPACE_PATH, projectID: process.env.C9_HOSTNAME }; workspace = new Workspace({ path: received.path, projectID: received.projectID }); if (callback) { callback(null, received); } } // Commands this.sendIndex = function () { log('sendIndex'); const { deviceID } = this.deviceInfo; try { sendResetTimeout.set(deviceID, () => { sendRequest(DEVICE, 'resetTimeout', messageFactory.createMessage('resetTimeout')); }); workspace.getIndex(self.deviceInfo, (err, indexData) => { sendResetTimeout.clear(deviceID); global.shared.allDeviceInfos[self.deviceInfo.deviceID].indexData = indexData; sendRequest(DEVICE, null, messageFactory.createMessage('getFiles', indexData)); }); } catch (ex) { sendResetTimeout.clear(deviceID); sendRequest(DEVICE, null, messageFactory.createMessage('getFiles', null)); } }; this.start = function (type) { log('start'); const message = messageFactory.createMessage('start', type); sendRequest(DEVICE, null, message); }; this.stop = function (type) { log('stop'); const message = messageFactory.createMessage('stop', type); sendRequest(DEVICE, null, message); }; this.erase = function () { log('erase'); const message = messageFactory.createMessage('erase'); sendRequest(DEVICE, null, message); }; this.ping = function () { log('ping'); const message = messageFactory.createMessage('ping'); sendRequest(DEVICE, null, message); }; this.openUrl = function (url) { log('openUrl'); const message = messageFactory.createMessage('openUrl', { url }); sendRequest(DEVICE, null, message); }; // Communication function sendRequest(to, command, message, callback) { if (callback) { callbackList[message.id] = callback; } request(MESSAGE, to, command, message); } } module.exports = ControlService;