Skip to content
Permalink
Browse files

Adding stability with clusters and domains.

  • Loading branch information...
roncli committed Jun 26, 2015
1 parent 04edde0 commit f4af7835a952c879e678f33b7b89b0748dace1af
Showing with 169 additions and 38 deletions.
  1. +59 −34 index.js
  2. +22 −4 public/js/ddsn.js
  3. +48 −0 webserver.js
  4. +40 −0 websocket.js
@@ -1,40 +1,65 @@
var express = require("express"),
app = express(),
WebSocket = require("ws"),
wss = new WebSocket.Server({port: 20921});
var cluster = require("cluster"),
webserver = require("./webserver"),
websocket = require("./websocket"),
webServerWorker, webSocketWorker;

// Setup web server.
app.use(function(req, res, next) {
"use strict";

if (req.headers.host === "localhost:20920") {
next();
} else {
res.status(404).send("Not found");
}
});

app.use(express.static("public"));

app.get("/quit", function(req, res) {
"use strict";

res.status(200).send("Descent DSN has been force quit. You should close all other running Descent 3 servers manually.");

process.exit();
});

app.listen(20920);
// Use clustering to spawn separate processes.
if (cluster.isMaster) {
webServerWorker = cluster.fork({
ddsnJob: "webserver"
});
webSocketWorker = cluster.fork({
ddsnJob: "websocket"
});

// Setup web sockets.
wss.on("connection", function(ws) {
"use strict";
cluster.on("disconnect", function(worker) {
"use strict";

ws.on("message", function(ev) {
// TODO: Handle message.
if (worker.suicide) {
// Worker was intentionally disconnected, end the application.
if (webServerWorker.isConnected()) {
webServerWorker.kill();
}
if (webSocketWorker.isConnected()) {
webSocketWorker.kill();
}
process.exit();
} else {
// Worker was unintentionally disconnected, restart any disconnected workers.
if (!webServerWorker.isConnected()) {
webServerWorker = cluster.fork({
ddsnJob: "webserver"
});
}
if (!webSocketWorker.isConnected()) {
webSocketWorker = cluster.fork({
ddsnJob: "websocket"
});
}
}
});

ws.on("error", function(ev) {
// TODO: Handle error.
cluster.on("exit", function() {
"use strict";

if (!webServerWorker.isConnected()) {
webServerWorker = cluster.fork({
ddsnJob: "webserver"
});
}
if (!webSocketWorker.isConnected()) {
webSocketWorker = cluster.fork({
ddsnJob: "websocket"
});
}
});
});
} else {
switch (process.env.ddsnJob) {
case "webserver":
webserver();
break;
case "websocket":
websocket();
break;
}
}
@@ -1,16 +1,27 @@
/*jslint browser: true*/
/*global $, WebSocket*/
$(document).ready(function() {

var createWebsocketClient = function() {
"use strict";

var ws = new WebSocket("ws://localhost:20921");
var ws = new WebSocket("ws://localhost:20921"),
connected = false;

ws.onopen = function() {
// TODO: Request initialization data.
ws.send(JSON.stringify({
message: "initialize"
}));
connected = true;
};

ws.onclose = function() {
// TODO: Shut down the web page.
// If the server shut down, attempt to reconnect once.
console.log("Closed.");
if (connected) {
setTimeout(function() {
createWebsocketClient();
}, 1000);
}
};

ws.onmessage = function(ev) {
@@ -19,5 +30,12 @@ $(document).ready(function() {

ws.onerror = function(ev) {
// TODO: Display error and shut down the web page.
console.log("An error occurred.", ev);
};
};

$(document).ready(function() {
"use strict";

createWebsocketClient();
});
@@ -0,0 +1,48 @@
var cluster = require("cluster"),
domain = require("domain"),
express = require("express");

module.exports = function() {
"use strict";

var d = domain.create(),
server;

// Run the web server in a domain.
d.run(function() {
var app = express();

// Only allow connections on the localhost.
app.use(function(req, res, next) {
if (req.headers.host === "localhost:20920") {
next();
} else {
res.status(404).send("Not found");
}
});

// Allow for static content in the public directory.
app.use(express.static("public"));

// Force quit Descent DSN entirely.
app.get("/quit", function(req, res) {
res.status(200).send("Descent DSN has been force quit. You should close all other running Descent 3 servers manually.");
server.close();
cluster.worker.kill();
});

// Create the server.
server = app.listen(20920);
});

// Log any errors and restart the worker.
d.on("error", function(err) {
console.log("An error occurred:", err);

if (server) {
server.close();
}
cluster.worker.disconnect();
process.exit();
});
};
@@ -0,0 +1,40 @@
var cluster = require("cluster"),
domain = require("domain"),
WebSocket = require("ws");

module.exports = function() {
"use strict";

var d = domain.create(),
wss;

// Run the WebSocket server in a domain.
d.run(function() {
wss = new WebSocket.Server({port: 20921});

// Listen for new connections.
wss.on("connection", function(ws) {

// Parse any messages.
ws.on("message", function(data) {
var message = JSON.parse(data);

switch (message.message) {
case "initialize":
break;
}
});
});
});

// Log any errors and restart the worker.
d.on("error", function(err) {
console.log("An error occurred:", err);

if (wss) {
wss.close();
}
cluster.worker.disconnect();
process.exit();
});
};

0 comments on commit f4af783

Please sign in to comment.
You can’t perform that action at this time.