UNPKG

devil-windows

Version:

Debugger, profiler and runtime with embedded WebKit DevTools client (for Windows).

196 lines (154 loc) 5.44 kB
var util = require('util'), EventEmitter = require('events').EventEmitter, WebSocket = require('../../lib/ws'); function Client (src) { var $this = this; var _host = null; var _port = null; var _ws = null; var _running = false; var _paused = false; var _connected = false; var _requests = {}; var _nextId = 1; var _token = null; var _messageHandler = function (message) { console.log("[MESSAGE]", message); try { var data = JSON.parse(message); } catch (e) { $this.emit("error", "Cannot parse JSON message from server."); return; } if (typeof data !== 'object') { return $this.emit("error", "A JSON message from the server is not an object."); } if (!data.id) { // Notification $this.emit(data.method + 'Notification', data.params); } else { // Response if (!_requests[data.id]) return $this.emit("error", "Got response twice? Not existing id."); var fn = _requests[data.id]; delete _requests[data.id]; fn(data.error, data.params); } }; var _request = function (method, params, callback) { if (!params) params = {}; var data = { params: params }; data.id = _nextId ++; data.method = method; _requests[data.id] = callback; _ws.send(JSON.stringify(data)); }; this.on('connectedNotification', function (data) { _token = data.token; $this.emit('connect', _token); }); this.on('stopNotification', function (data) { $this.emit('stop'); _running = false; _paused = false; }); this.on('pauseNotification', function (data) { $this.emit('pause'); _paused = true; }); this.on('resumeNotification', function (data) { $this.emit('resume'); _paused = false; }); this.on('errorNotification', function (data) { $this.emit('error', data); }); this.connect = function (host, port, callback) { if (_connected || _ws) this.disconnect(); console.log("[INFO] Connecting to " + host + ":" + port); var tmp = false; var _cb = function (err) { if (!tmp) callback(err); else { tmp = true; if (err) $this.disconnect(err); } }; _host = host; _port = port; _ws = new WebSocket('ws://' + _host + ':' + _port); _ws.on('open', function () { _ws.send('Greetings, Master!'); }); _ws.once('message', function (message) { console.log("[MESSAGE]", message); if (message == 'Don\'t speak to me, scum, I am the Devil!') { $this.once('connect', _cb.bind($this, null)); _connected = true; _ws.on('message', _messageHandler); } else { // THis is not our server. Get out of here. _cb(new Error("This is not a devil server.")); } }); _ws.on('close', function () { console.log("[ERROR] WebSocket closed."); _cb(new Error('Connection closed.')); }); _ws.on('error', function (err) { console.log("[ERROR]", err); _cb(err); }); }; this.disconnect = function (error) { console.log("[INFO] Disconnecting from " + _host + ":" + _port); if (_ws) { _ws.removeAllListeners(); _ws.close(); } this.emit('disconnect', error); _running = false; _paused = false; _connected = false; _ws = null; }; this.run = function (options, callback) { if (_running) return callback(new Error('Already running.')); // The server will initialize a new session and send a ready event. _request('run', options, function (err, data) { if (err) return callback(err); src('devtools/devtools.html?ws=' + _host + ':' + _port + '/' + _token); _running = true; callback(); }); }; this.pause = function (callback) { if (!_running) return callback(new Error('Not running.')); if (_paused) return callback(); _request('pause', null, function (err, data) { if (err) return callback(err); _paused = true; callback(); }); }; this.resume = function (callback) { if (!_running) return callback(new Error('Not running.')); if (!_paused) return callback(); _request('resume', null, function (err, data) { if (err) return callback(err); _paused = false; callback(); }); }; this.stop = function (callback) { if (!_running) return callback(new Error('Not running.')); _request('stop', null, function (err, data) { if (err) return callback(err); $this.emit('stop'); callback(); }); }; } util.inherits(Client, EventEmitter); module.exports = Client;