Merge pull request #924 from QNimbus/client-only-pr

Added clientonly script
This commit is contained in:
Michael Teeuw 2017-07-12 11:08:04 +02:00 committed by GitHub
commit 86ae704e86
7 changed files with 121 additions and 6 deletions

View File

@ -5,9 +5,13 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [2.1.3] - Unreleased ## [2.1.3] - Unreleased
### Changed ### Changed
### Added ### Added
- Add `clientonly` script to start only the electron client for a remote server.
- Add symbol and color properties of event when `CALENDAR_EVENTS` notification is broadcasted from `default/calendar` module. - Add symbol and color properties of event when `CALENDAR_EVENTS` notification is broadcasted from `default/calendar` module.
### Updated ### Updated
### Fixed ### Fixed
- Fixed issue with incorrect allignment of analog clock when displayed in the center column of the MM - Fixed issue with incorrect allignment of analog clock when displayed in the center column of the MM

View File

@ -48,6 +48,11 @@ bash -c "$(curl -sL https://raw.githubusercontent.com/MichMich/MagicMirror/maste
### Server Only ### Server Only
In some cases, you want to start the application without an actual app window. In this case, you can start MagicMirror² in server only mode by manually running `node serveronly` or using Docker. This will start the server, after which you can open the application in your browser of choice. Detailed description below. In some cases, you want to start the application without an actual app window. In this case, you can start MagicMirror² in server only mode by manually running `node serveronly` or using Docker. This will start the server, after which you can open the application in your browser of choice. Detailed description below.
### Client Only
When you have a server running remotely and want to connect a standalone client to this instance, you can manually run `node clientonly --address 192.168.1.5 --port 8080`. (Specify the ip address and port number of the server)
**Important:** Make sure that you whitelist the interface/ip in the server config where you want the client to connect to, otherwise it will not be allowed to connect to the server
#### Docker #### Docker
MagicMirror² in server only mode can be deployed using [Docker](https://docker.com). After a successful [Docker installation](https://docs.docker.com/engine/installation/) you just need to execute the following command in the shell: MagicMirror² in server only mode can be deployed using [Docker](https://docker.com). After a successful [Docker installation](https://docs.docker.com/engine/installation/) you just need to execute the following command in the shell:

97
clientonly/index.js Normal file
View File

@ -0,0 +1,97 @@
/* jshint esversion: 6 */
"use strict";
// Use seperate scope to prevent global scope pollution
(function () {
var config = {};
// Helper function to get server address/hostname from either the commandline or env
function getServerAddress() {
// Helper function to get command line parameters
// Assumes that a cmdline parameter is defined with `--key [value]`
function getCommandLineParameter(key, defaultValue = undefined) {
var index = process.argv.indexOf(`--${key}`);
var value = index > -1 ? process.argv[index + 1] : undefined;
return value !== undefined ? String(value) : defaultValue;
}
// Prefer command line arguments over environment variables
["address", "port"].forEach((key) => {
config[key] = getCommandLineParameter(key, process.env[key.toUpperCase()]);
})
}
function getServerConfig(url) {
// Return new pending promise
return new Promise((resolve, reject) => {
// Select http or https module, depending on reqested url
const lib = url.startsWith("https") ? require("https") : require("http");
const request = lib.get(url, (response) => {
var configData = "";
// Gather incomming data
response.on("data", function(chunk) {
configData += chunk;
});
// Resolve promise at the end of the HTTP/HTTPS stream
response.on("end", function() {
resolve(JSON.parse(configData));
});
});
request.on("error", function(error) {
reject(new Error(`Unable to read config from server (${url} (${error.message}`));
});
})
};
function fail(message, code = 1) {
if (message !== undefined && typeof message === "string") {
console.log(message);
} else {
console.log("Usage: 'node clientonly --address 192.168.1.10 --port 8080'");
}
process.exit(code);
}
getServerAddress();
(config.address && config.port) || fail();
// Only start the client if a non-local server was provided
if (["localhost", "127.0.0.1", "::1", "::ffff:127.0.0.1", undefined].indexOf(config.address) === -1) {
getServerConfig(`http://${config.address}:${config.port}/config/`)
.then(function (config) {
// Pass along the server config via an environment variable
var env = Object.create(process.env);
var options = { env: env };
config.address = config.address;
config.port = config.port;
env.config = JSON.stringify(config);
// Spawn electron application
const electron = require("electron");
const child = require("child_process").spawn(electron, ["js/electron.js"], options);
// Pipe all child process output to current stdout
child.stdout.on("data", function (buf) {
process.stdout.write(`Client: ${buf}`);
});
// Pipe all child process errors to current stderr
child.stderr.on("data", function (buf) {
process.stderr.write(`Client: ${buf}`);
});
child.on("error", function (err) {
process.stdout.write(`Client: ${err}`);
});
})
.catch(function (reason) {
fail(`Unable to connect to server: (${reason})`);
});
} else {
fail();
}
}());

View File

@ -9,6 +9,7 @@
*/ */
var config = { var config = {
address: "localhost",
port: 8080, port: 8080,
ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], // Set [] to allow all IP addresses ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], // Set [] to allow all IP addresses
// or add a specific IPv4 of 192.168.1.5 : // or add a specific IPv4 of 192.168.1.5 :

View File

@ -8,10 +8,12 @@
*/ */
var port = 8080; var port = 8080;
var address = "localhost";
if (typeof(mmPort) !== "undefined") { if (typeof(mmPort) !== "undefined") {
port = mmPort; port = mmPort;
} }
var defaults = { var defaults = {
address: address,
port: port, port: port,
kioskmode: false, kioskmode: false,
electronOptions: {}, electronOptions: {},

View File

@ -6,7 +6,7 @@ const electron = require("electron");
const core = require(__dirname + "/app.js"); const core = require(__dirname + "/app.js");
// Config // Config
var config = {}; var config = process.env.config ? JSON.parse(process.env.config) : {};
// Module to control application life. // Module to control application life.
const app = electron.app; const app = electron.app;
// Module to create native browser window. // Module to create native browser window.
@ -47,7 +47,7 @@ function createWindow() {
// and load the index.html of the app. // and load the index.html of the app.
//mainWindow.loadURL('file://' + __dirname + '../../index.html'); //mainWindow.loadURL('file://' + __dirname + '../../index.html');
mainWindow.loadURL("http://localhost:" + config.port); mainWindow.loadURL(`http://${config.address}:${config.port}`);
// Open the DevTools if run with "npm start dev" // Open the DevTools if run with "npm start dev"
if (process.argv.includes("dev")) { if (process.argv.includes("dev")) {
@ -96,8 +96,10 @@ app.on("activate", function() {
} }
}); });
// Start the core application. // Start the core application if server is run on localhost
// This starts all node helpers and starts the webserver. // This starts all node helpers and starts the webserver.
core.start(function(c) { if (["localhost", "127.0.0.1", "::1", "::ffff:127.0.0.1", undefined].indexOf(config.address) > -1) {
core.start(function (c) {
config = c; config = c;
}); });
}

View File

@ -52,6 +52,10 @@ var Server = function(config, callback) {
res.send(global.version); res.send(global.version);
}); });
app.get("/config", function(req,res) {
res.send(config);
});
app.get("/", function(req, res) { app.get("/", function(req, res) {
var html = fs.readFileSync(path.resolve(global.root_path + "/index.html"), {encoding: "utf8"}); var html = fs.readFileSync(path.resolve(global.root_path + "/index.html"), {encoding: "utf8"});
html = html.replace("#VERSION#", global.version); html = html.replace("#VERSION#", global.version);