I build a sample code in node js
var cluster = require("cluster"),
http = require("http"),
express = require('express'),
port = parseInt(process.argv[2]||8001),
servers = ['http://127.0.0.1:800821', 'http://127.0.0.1:800831'];;
if (cluster.isMaster) {
console.log('Master ' + process.pid + ' has started.');
var numWorkers = require('os').cpus().length;
console.log('Master cluster setting up ' + numWorkers + ' workers...');
for(var i = 0; i < 1; i++) {
cluster.fork();
}
cluster.on('online', function(worker) {
console.log('Worker ' + worker.process.pid + ' is online');
});
cluster.on('exit', function(worker, code, signal) {
console.log('Worker ' + worker.process.pid + ' died with code: ' + code + ', and signal: ' + signal);
console.log('Starting a new worker');
cluster.fork();
});
} else {
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer();
var count = 0;
// Workers share the TCP connection in this server
var app = express();
app.get('/', function (req, res) {
console.log('Cluster => ' + process.pid);
loadBalanceProxy(req,res);
}).listen(port);
var currentServer = 1;
function loadBalanceProxy(req, res){
var cur = currentServer%servers.length;
currentServer++;
var target = servers[cur];
console.log("Proxy => " + target);
proxy.web(req, res, {
target: target
});
}
}
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('request successfully proxied to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2));
res.end();
}).listen(800831);
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('request successfully proxied to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2));
res.end();
}).listen(800821);
In this sample, I want to create proxy server inside cluster worker and this give me error bind EADDRINUSE null:800831
I want to know can I create http-proxy inside cluster worker. If I can't then there's solution for load balance between machines ?
I create a proxy reverse exemple proxy reverse inside cluster and i create 3 servers in another files, it works for me (dont forget to run the servers separately for example on windows you launch servers in 4 cmd, 1 cmd for proxy and other (3 cmd) for servers )
// var https = require('https'); scure
var http = require('http');
var proxy = require('http-proxy');
var cluster = require('cluster');
var fs = require('fs');
var request = require('request');
// const numCPUs = require('os').cpus().length;
var numCPUs = 4;
if (cluster.isMaster) {
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('fork', (worker) => {
console.log('worker ' + worker.process.pid);
});
cluster.on('exit', function(worker, code, signal) {
console.log('Worker ' + worker.process.pid + ' died with code: ' + code + ', and signal: ' + signal);
console.log('Starting a new worker');
cluster.fork();
});
} else {
startProxyReverse();
}
function startProxyReverse() {
http.globalAgent.maxSockets = 10240;
// Define the servers to load balance.
var servers = [{
host: '127.0.0.1',
port: 8001
}, {
host: '127.0.0.1',
port: 8003
}, {
host: '127.0.0.1',
port: 8002
}];
var failoverTimer = [];
// load the SSL cert
// var ca = [
// fs.readFileSync('./certs/PositiveSSLCA2.crt'),
// fs.readFileSync('./certs/AddTrustExternalCARoot.crt')
// ];
// var opts = {
// ca : ca,
// key : fs.readFileSync('./certs/example_wild.key'),
// cert : fs.readFileSync('./certs/STAR_example_com.crt')
// };
// Create a proxy object for each target.
var proxies = servers.map(function(target) {
return new proxy.createProxyServer({
target: target
// ws : true,
// xfwd : true,
// ssl : opts,
// down : false
});
});
/**
* Select a random server to proxy to. If a 'server' cookie is set, use that
* as the sticky session so the user stays on the same server (good for ws fallbacks).
* #param {Object} req HTTP request data
* #param {Object} res HTTP response
* #return {Number} Index of the proxy to use.
*/
var selectServer = function(req, res) {
var index = -1;
var i = 0;
// Check if there are any cookies.
if (req.headers && req.headers.cookie && req.headers.cookie.length > 1) {
var cookies = req.headers.cookie.split('; ');
for (i = 0; i < cookies.length; i++) {
if (cookies[i].indexOf('server=') === 0) {
var value = cookies[i].substring(7, cookies[i].length);
if (value && value !== '') {
index = value;
break;
}
}
}
}
// Select a random server if they don't have a sticky session.
if (index < 0 || !proxies[index]) {
index = Math.floor(Math.random() * proxies.length);
}
// If the selected server is down, select one that isn't down.
if (proxies[index].options.down) {
index = -1;
var tries = 0;
while (tries < 5 && index < 0) {
var randIndex = Math.floor(Math.random() * proxies.length);
if (!proxies[randIndex].options.down) {
index = randIndex;
}
tries++;
}
}
index = index >= 0 ? index : 0;
// Store the server index as a sticky session.
if (res) {
res.setHeader('Set-Cookie', 'server=' + index + '; path=/');
}
return index;
};
/**
* Fired when there is an error with a request.
* Sets up a 10-second interval to ping the host until it is back online.
* There is a 10-second buffer before requests start getting blocked to this host.
* #param {Number} index Index in the proxies array.
*/
var startFailoverTimer = function(index) {
if (failoverTimer[index]) {
return;
}
failoverTimer[index] = setTimeout(function() {
// Check if the server is up or not
request({
url: 'http://' + proxies[index].options.target.host + ':' + proxies[index].options.target.port,
method: 'HEAD',
timeout: 10000
}, function(err, res, body) {
failoverTimer[index] = null;
if (res && res.statusCode === 200) {
proxies[index].options.down = false;
console.log('Server #' + index + ' is back up.');
} else {
proxies[index].options.down = true;
startFailoverTimer(index);
console.log('Server #' + index + ' is still down.');
}
});
}, 10000);
};
// Select the next server and send the http request.
var serverCallback = function(req, res) {
console.log('Process ' + process.pid + ' is listening to all incoming requests');
var proxyIndex = selectServer(req, res);
console.log(proxyIndex);
var proxy = proxies[proxyIndex];
proxy.web(req, res);
proxy.on('error', function(err) {
startFailoverTimer(proxyIndex);
});
};
console.log('create server');
// var server = http.createServer(opts, serverCallback); scure server
var server = http.createServer(serverCallback);
// http.createServer(serverCallback).listen(8000);
// Get the next server and send the upgrade request.
// server.on('upgrade', function (req, socket, head) {
// var proxyIndex = selectServer(req);
// var proxy = proxies[proxyIndex];
// proxy.ws(req, socket, head);
// proxy.on('error', function (err, req, socket) {
// socket.end();
// startFailoverTimer(proxyIndex);
// });
// });
server.listen(8000);
// server.listen(443); scure port
// var proxi = proxy.createServer();
// http.createServer(function (req, res) {
// var target = {
// target : servers.shift()
// };
// console.log('Process ' + process.pid + ' is listening to all incoming requests');
// console.log('balancing request to: ', target);
// proxi.web(req, res, target);
// servers.push(target.target);
// }).listen(8000);
}
Ports should in 1-65535 range.
Related
I am writing a Proof Of Concept (for at least 2 months now) that uses Node cluster (workers), Redis and socket.io.
Socket.io is not in use for chat in this instance - just back to front communication. Ajax is not an option.
I am using pub/sub for redis and have that piece working (I think). At least the values returned from pubClient.get('key') are correct.
When I make a request from the front end and do not navigate or reload the page in any way, things work perfectly - I can make 10 requests and 10 responses are received.
Conversely, when I navigate, the same is not true - and I need to deliver the results no matter how much someone navigates on the front end.
It seems there is a disconnect after a reload. In both consoles - Dev Tools and node js, the socket ids are the same. I'm really scratching my head on this one!
Any help out there?
So, for some mainly socket.io code:
CLIENT:
socket = io('https://' + location.hostname + ':4444/', {
transports: ['websocket', 'polling'],
secure: true,
});
socket.on('download', function(data){// after reload, this never hits
console.log('DOWNLOAD '+ data.download);
});
var pkgs = ['y14Vfk617n6j', 'My77gWYmBLxT', 'IYd6dL9UoXkx'];
if(pkgs.length > 0){
for(var i = 0; i < pkgs.length; i++){
socket.emit('get-request', pkgs[i]);
}
}
SERVER:
var cluster = require('cluster');
var express = require('express');
var numCPUs = require('os').cpus().length;
const { setupMaster, setupWorker } = require("#socket.io/sticky");
const { createAdapter, setupPrimary } = require("#socket.io/cluster-adapter");
var app = express();
const https = require('https');
const { Server } = require("socket.io");
const Redis = require("ioredis");
const sock_nodes = [
{port: 6379, host: '192.168.0.41'},
{port: 6380, host: '192.168.0.34'},
{port: 6381, host: '192.168.0.35'},
{port: 6379, host: '192.168.0.34'},
{port: 6380, host: '192.168.0.35'},
{port: 6381, host: '192.168.0.41'}
];
const port = 4444;
const httpServer = https.createServer(options, app);
const io = new Server(httpServer, {maxHttpBufferSize: 10240000});
const pubClient = new Redis.Cluster(sock_nodes, {
redisOptions: {
password: 'my secret!'
}
});
const subClient = pubClient.duplicate(); // I am not actually using this - should I be?
if (cluster.isMaster) {
for (var i = 0; i < numCPUs; i++) {
// Create a worker
cluster.fork();
}
cluster.on("exit", (worker) => {
console.log(`Worker PID ${worker.process.pid} died`);
var w = cluster.fork();
console.log('WORKER %d died (%s). restarting...', worker.process.pid, worker.state);
w.on('message', function(msg){
console.log("Message Received : " , msg);
});
});
} else {
app.use((req, res, next) => {
var reqip = req.headers['x-real-ip'] || req.headers['x-forwarded-for'] || req.connection.remoteAddress;
//~ console.log(reqip, md5(reqip));
var sess = parseCookies(req, 'session_state');
if(!sess){
res.cookie('session_state', md5(reqip));
}
next();
});
app.get('/', (req, res) => {
getSession(req, res, function(sess){
getPub('currSockets', sess, function(err, socket){
res.render("pages/shared/index", {'ns': sess, 'socket': socket});
});
});
});
});
app.get('/start', function(req, res){
getSession(req, res, function(sess){
getPub('currSockets', sess, function(err, socket){
res.render("pages/shared/start", {'ns': sess, 'socket': socket});
});
});
});
io.on('connection', function (socket) {
var currUser = parseCookies(socket.request, 'session_state');
socket.join(currUser);
getPub('currSockets', currUser, function(err, currSockets){
if (currSockets) {
currSockets = JSON.parse(currSockets);
if (currSockets[currUser]) {
if (currSockets[currUser].stream) {
currSockets[currUser].sock = socket.id;
setCurrSockets(currSockets, currUser, null, function(cSocks){
});
}
}
}
});
socket.on('get-request', function(data){ // can be one or many requests
// there is a similar, currently irrelevant, socket.on('new-request') that is left out here
if(data){
getPub('currSockets', currUser, function(err, currSockets){
currSockets = JSON.parse(currSockets);
if(currSockets){
if(currUser){
if(currSockets[currUser]){
if(currSockets[currUser].stream){
var str = Object.keys(currSockets[currUser].stream);
for(var i = 0; i < str.length; i++){
if(str[i] !== 'sock'){
if(!currSockets[currUser].stream[str[i]]){
delete currSockets[currUser].stream[str[i]];
setCurrSockets(currSockets, currUser, null, function(cSocks){
checkCurrSockets(currUser, data, socket);
});
}
}
}
}
}
}
}
});
}
});
});
httpServer.listen(port, () => {
logs(__line__, `Worker ${process.pid} listening on ${port}`);
});
}
function existsPub(key, cb){
return pubClient.exists(key, cb);
}
function setPub(key, val, cb){
if(val === JSON.stringify({})){
return pubClient.get(key, cb);
}
return pubClient.set(key, val, cb);
}
function getPub(key, currUser, cb){
existsPub(key, function(err, reply){
if(reply === 1){
return pubClient.get(key, cb);// always getting an old socket.id
}
});
}
// Here is the piece that doesn't work after reloading the page
function ioEmit (currSock, target, payload) {
io.to(currSock).emit(target, payload); // doesn't work after page reload
}
// end piece where after reload does not work
getPub('currSockets', currUser, function(err, currSockets){
if( currSockets){
currSockets = JSON.parse(currSockets);
ioEmit(currUser, 'download', {'download': currSockets[currUser].stream[data]);
}
});
function parseCookies (req, name) {
var list = {}, rc;
rc && rc.split(';').forEach(function( cookie ) {
var parts = cookie.split('=');
list[parts.shift().trim()] = decodeURI(parts.join('='));
});
return list[name];
}
function getSession(req, res, callback) {
var sess = false;
if(req.headers) {// handle req
var reqip = req.headers['x-real-ip'] || req.headers['x-forwarded-for'] || req.connection.remoteAddress;
if(req.headers.cookie){
sess = req.headers.cookie.split('=')[1].split(';')[0];
} else {
res.cookie('session_state', md5(reqip));
}
return callback(sess);
} else if(req.request) {// handle socket
//~ console.log('req.request.headers.cookie', req.request.headers.cookie.split('=')[1]);
if(req.request.headers.cookie){
sess = req.request.headers.cookie.split('=')[1].split(';')[0];
//~ req.emit('join', sess);
//~ callback({[sess]: {'sock': req.id}});
callback(req.id);
}
} else {
return callback(null);
}
}
function setCurrSockets(currSockets, currUser, data, cb){
if(Object.keys(currSockets[currUser].stream).length > 0){
if(data){
if(ready(currSockets, currUser, data)){
delete currSockets[currUser].stream[data];// it appears that setCurrSockets is getting called too soon
}
}
setPub('currSockets', JSON.stringify(currSockets), function(err){
});
if(typeof cb === 'function'){
setTimeout(() => {
getPub('currSockets', currUser, function(err, cSocks){
cb(cSocks);// updated callback to return cSocks
}, 2000);
});
}
} else {
currSockets[currUser].stream = {};
setPub('currSockets', JSON.stringify(currSockets), function(err){
if(err){
} else {
if(typeof cb === 'function'){
cb(currSockets);// updated callback to return cSocks
}
}
});
}
}
figured this out. The problem was in here:
for(var i = 0; i < str.length; i++){
if(str[i] !== 'sock'){
>>>> if(!currSockets[currUser].stream[str[i]]){ // never true
// delete currSockets[currUser].stream[str[i]];
setCurrSockets(currSockets, currUser, null, function(cSocks){
checkCurrSockets(currUser, data, socket);
});
}
}
}
so I commented the for loop and kept the setCurrSockets part and it works.
Just thought I would share, in case someone else tries to use redis, node cluster and socket.io together. As #jfreind00 said, you should use an authentication system with a randomly gen'd string for storing cookies.
Every time a user enter to our URL he get the response of the last user + his new response.
I'm new with nodejs and I think I don't understand the way this server works :)
Anyway, here you can see the app:
https://s1-nodejs.herokuapp.com (You will need to reload the page to see the duplicate response every time you reload).
And this is the code I deployed to Heroku:
const start = Date.now();
// using the http module
var http = require('http');
var https = require('https');
var request = require('request');
var domain;
var apiKey = 'example';
var domainResultJson = [];
var promises = [];
// look for PORT environment variable,
// else look for CLI argument,
// else use hard coded value for port 8080
port = process.env.PORT || process.argv[2] || 8080;
// create a simple server
let server = http.createServer(function (req, res) {
for (var i = 0 ; i < 10 ; i++ ) {
var domain = 'example-'+i+'.com';
promises.push(CheckIfDomainAvailable(https,domain,apiKey,domainResultJson));
}
Promise.all(promises).then(function(values) {
//console.log(values);
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
for (var i in values) {
val = values[i];
res.write(val);
}
res.end();
}).catch(
console.error
);
function CheckIfDomainAvailable(https,domain,apiKey,domainResultJson) {
return new Promise(function (success, failure) {
request('https://example.com/api/v1?'
+ 'apiKey=' + apiKey + '&d=' + domain + '', function (error, response, body) {
if (!error && response.statusCode == 200) {
domainResultJson.push('1');
success(body);
} else {
failure(error);
}
});
});
}
});
// listen on the port
server.listen(port, function () {
console.log('app up on port: ' + port);
});
Try to declare let promises = []; inside function (req, res) { ... }, like this:
// ...
let server = http.createServer(function (req, res) {
let promises = []; // <= Define promises container here.
for (var i = 0 ; i < 10 ; i++ ) {
var domain = 'example-'+i+'.com';
promises.push(CheckIfDomainAvailable(https,domain,apiKey,domainResultJson));
}
// ...
I am requesting an index.djvu that fires requests for documents by id. The requests id that the index.djvu fires is Base64 encoded e.g document/page_1_1_1_k21g_MjE4MGstMTAvMTE=.djvu where the id is MjE4MGstMTAvMTE=.
I need to encode the id before the requests is sent e.g encodeURIComponent('MjE4MGstMTAvMTE=').
How can I get control over the requests that the index.djvu fires?
My code looks like this
var http = require('http');
var httpProxy = require('http-proxy');
var HttpProxyRules = require('http-proxy-rules');
var proxyRules = new HttpProxyRules({
rules: {
// This requests response index further requests explained
'.*/document': 'https://api.service.xxx/document/index.djvu?archive=21&id=2180k-10/11'
},
default: 'https://api.service.xxx/document'
});
var proxy = httpProxy.createProxyServer({
secure: false
});
proxy.on('proxyReq', function (proxyReq, req, res, options) {
proxyReq.setHeader('Authorization', 'Bearer xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx');
});
var server = {};
server.httpServer = http.createServer(function (req, res) {
var target = proxyRules.match(req);
if (target) {
return proxy.web(req, res, {
target: target
});
}
});
server.init = () => {
server.httpServer.listen(9000, () => {
console.log('\x1b[36m%s\x1b[0m', 'The HTTP server is running on port 9000');
});
}
server.init();
server.httpServer.on('error', function (err) {
console.log('Error http-server\n', JSON.stringify(err));
});
proxy.on('proxyRes', function (proxyRes, req, res) {
console.log('Status: ' + proxyRes.statusCode + ' ' + proxyRes.statusMessage);
proxyRes.on('data', function (chunk) {
console.log('Body: ' + chunk.toString('utf8'));
});
console.log('Headers received from api: ', JSON.stringify(proxyRes.headers, true, 2));
});
All help is appreciated
This solved it after several hours of war ;)
var http = require('http');
var httpProxy = require('http-proxy');
var url = require('url');
var proxy = httpProxy.createProxyServer({
target: 'https://api.xxxxxxxxxxxxxx.xxx',
secure: false
}).listen(9000);
proxy.on('proxyReq', function (proxyReq, req, res, options) {
proxyReq.setHeader('Authorization', 'Bearer xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx');
var url_parts = url.parse(req.url);
var str = url_parts.pathname;
var query = url_parts.search;
if (str) {
var path = str.split("_");
urlstring = {
page_: path[0],
vers: path[1],
subdoc: path[2],
page: path[3],
archive: path[4],
enc_id: path[5]
}
}
var rewritedPath;
if (str.includes('route')) {
rewritedPath = '/xxx' + str;
} else if (str.includes('route')) {
var index = '/xxx' + str + query;
rewritedPath = index;
} else {
var page = 'xxx' + urlstring.page_ + '_' + urlstring.vers + '_' + urlstring.subdoc + '_' + urlstring.page + '_' + urlstring.archive + '_' + encodeURIComponent(urlstring.enc_id);
rewritedPath = page;
}
proxyReq.path = rewritedPath;
});
proxy.on('error', function (err, req, res) {
console.log('Something went wrong.', err);
});
proxy.on('proxyRes', function (proxyRes, req, res) {
// console.log('Status: ' + req.url + ' ' + proxyRes.statusMessage);
// proxyRes.on('data', function (chunk) {
// console.log('Body: ' + chunk.toString('utf8'));
// });
// console.log('Headers: ', JSON.stringify(proxyRes.headers, true, 2));
});
For a school project we had to develop a file server and also a chat server. I did both in Node.js. Now I have to merge them, but they're both supposed to listen on the same port.
I have two file which both work. The chat server uses
net.createServer(function (socket){
...
}}).listen(9020);
And the file server uses
http.createServer(function (request, response){
...
}}).listen(9020);
Simple putting all the code in the same file returns an error since you can't have two servers listening on the same port. What's the best way to merge them? Can all the code be run in either the Net or HTTP server? I've tried this but it isn't working for me.
Here's the full code:
chat.js
// Load the TCP Library
net = require('net');
// Keep track of the chat clients
var clients = [];
var chat = [];
// Start a TCP Server
net.createServer(function (socket) {
socket.setEncoding('utf8');
// Identify this client
socket.name = "unknown"
// Put this new client in the list
clients.push(socket);
// Send a nice welcome message and announce
socket.write("Welcome to Michael's chat room" + "\r\n");
//broadcast(socket.name + " joined the chat\r\n", socket);
// Handle incoming messages from clients.
socket.on('data', function (data) {
var textdata = data.toString();
if(textdata.trim() === "adios"){
broadcast("closing connection", socket);
socket.end();
}
else if (textdata.trim() === "help"){
broadcast("*******************Available commands:*******************\r\nhelp Display the program options\r\ntest: <words> Send a test message of <words> that does not get logged\r\nname: <chatname> Set name to <chatname>\r\nget Get the entire chat log\r\npush: <stuff> Add <stuff> to the chat log\r\ngetrange <startline> <endline> Get contents of the chat log from <startline> to <endline>\r\nadios Close connection");
}
else if (startsWith(textdata, "name:")){
var rmv = "name: ";
textdata = textdata.slice( textdata.indexOf( rmv ) + rmv.length );
socket.name = textdata.trim();
broadcast("OK\r\n", socket);
}
else if (startsWith(textdata, "push:")){
var rmv = "push: ";
textdata = textdata.slice( textdata.indexOf( rmv ) + rmv.length );
textdata = textdata.trim();
chat.push(socket.name + ": " + textdata + "\r\n");
broadcast("OK\r\n");
}
else if (startsWith(textdata, "test:")){ //Why do we even have this lever?
var rmv = "test: ";
textdata = textdata.slice( textdata.indexOf( rmv ) + rmv.length );
broadcast(textdata.trim() + "\r\n");
}
else if (textdata.trim() === "get"){
for (var i = 0; i < chat.length; ++i) {
//if (i < 1){
// broadcast(chat[i].toString(), socket);
//}
//else{
broadcast(chat[i].toString(), socket);
//}
}
}
else if (startsWith(textdata, "getrange")){
var rmv = "getrange ";
textdata = textdata.slice( textdata.indexOf( rmv ) + rmv.length );
var newtextdata = textdata;
newtextdata = newtextdata.split(" ");
var stringArray = new Array();
for(var i =0; i < newtextdata.length; i++){
stringArray.push(newtextdata[i]);
if(i != newtextdata.length-1){
//stringArray.push(" ");
}
}
for (var i = stringArray[0]; i <= stringArray[1]; ++i) {
broadcast(chat[i].toString() + "\r\n", socket);
}
}
else{
broadcast("Error: unrecognized command: " + textdata + "\r\n", socket);
}
});
// Remove the client from the list when it leaves
socket.on('end', function () {
clients.splice(clients.indexOf(socket), 1);
broadcast(socket.name + " left the chat.\r\n");
});
// Send a message to all clients
function broadcast(message, sender) {
clients.forEach(function (client) {
// Don't want to send it to sender
///if (client === sender) return; //actually want to send a lot of stuff only to sender - how to do this?
client.write(message);
});
// Log it to the server output too
process.stdout.write(message)
}
function startsWith(str, word) {
return str.lastIndexOf(word, 0) === 0;
}
socket.on('Error', function(err){
console.log("well heck, there's been an error")
});
}).listen(9020);
// Put a friendly message on the terminal of the server.
console.log("Chat server running at port 9020\r\n");
file.js
//based heavily off of https://developer.mozilla.org/en-US/docs/Node_server_without_framework
var http = require('http');
var fs = require('fs');
var path = require('path');
http.createServer(function (request, response) {
console.log('request ', request.url);
var filePath = '.' + request.url;
if (filePath == './')
filePath = './index.html';
if (filePath == './CHAT')
filePath = './chatform.html';
var extname = String(path.extname(filePath)).toLowerCase();
var contentType = 'text/html';
var mimeTypes = {
'.html': 'text/html',
'.js': 'text/javascript',
'.css': 'text/css',
'.json': 'application/json',
'.png': 'image/png',
'.jpg': 'image/jpg',
'.gif': 'image/gif',
};
contentType = mimeTypes[extname] || 'application/octect-stream';
fs.readFile(filePath, function(error, content) {
if (error) {
if(error.code == 'ENOENT'){
fs.readFile('./404.html', function(error, content) {
response.writeHead(200, { 'Content-Type': contentType });
response.end(content, 'utf-8');
});
}
else {
response.writeHead(500);
response.end('Sorry, check with the site admin for error: '+error.code+' ..\n');
response.end();
}
}
else {
response.writeHead(200, { 'Content-Type': contentType });
response.end(content, 'utf-8');
}
});
}).listen(9020);
console.log('Server running on port 9020');
I have been trying to figure out a way to connect a WiFly from an Arduino to send some accelerometer data to my node.js server. Currently the way that I have it worked out is having three servers:
Http >> This is for clients purposes
Net server >> This is basically for TCP request, this is how my server receives the information from 3. WS websockets >> this takes the data from the Net server and streams it to the client side.
Here is the code:
var http = require('http');
var fs = require('fs');
var path = require('path');
var url = require('url');
var net = require('net');
var sensorData;
var message = {
"data": ''
}
var newValue,
oldValue,
diff;
//Settings
var HTTP_PORT = 9000;
var NET_PORT = 9001;
var WS_PORT = 9002;
//Server
var mimeTypes = {
"html": "text/html",
"jpeg": "image/jpeg",
"jpg": "image/jpeg",
"png": "image/png",
"js": "text/javascript",
"css": "text/css"
};
http.createServer(function (req, res) {
var fileToLoad;
if (req.url == '/') {
fileToLoad = 'index.html';
} else {
fileToLoad = url.parse(req.url).pathname.substr(1);
}
console.log('[HTTP] :: Loading :: ' + 'frontend/' + fileToLoad);
var fileBytes;
var httpStatusCode = 200;
fs.exists('frontend/' + fileToLoad, function (doesItExist) {
if (!doesItExist) {
console.log('[HTTP] :: Error loading :: ' + 'frontend/' + fileToLoad);
httpStatusCode = 404;
}
var fileBytes = fs.readFileSync('frontend/' + fileToLoad);
var mimeType = mimeTypes[path.extname(fileToLoad).split('.')[1]];
res.writeHead(httpStatusCode, {
'Content-type': mimeType
});
res.end(fileBytes);
});
// console.log("[INIT] Server running on HTTP Port");
}).listen(HTTP_PORT);
proxy.on("close", function(){
console.log("Connection has closed");
});
proxy.on("end", function(){
console.log("Connection has ended");
});
var socket;
var clients = [];
var socketObject;
var server = net.createServer(function (socket) {
socketObject = socket;
socket.name = socket.remoteAddress + ":" + socket.remotePort;
clients.push(socket);
console.log(socket);
socket.write("HTTP/1.1 101", function () {
console.log('[CONN] New connection: ' + socket.name + ', total clients: ' + clients.length);
});
socket.setEncoding('utf8');
socket.on('error', function (data) {
console.log(data);
});
socket.on('end', function () {
console.log('[END] Disconnection: ' + socket.name + ', total clients: ' + clients.length);
});
socket.on('data', function (data) {
console.log('[RECV from ' + socket.remoteAddress + "] " + data);
oldValue = newValue;
newValue = data;
diff = Math.abs(newValue) - Math.abs(oldValue);
console.log(Math.abs(newValue) + '-' + Math.abs(oldValue));
message.data = Math.abs(diff);
console.log('[SAVED] ' + message.data);
});
});
server.listen(NET_PORT, function () {
console.log("[INIT] Server running on NET server port", NET_PORT);
});
var WebSocketServer = require('ws').Server,
wss = new WebSocketServer({
port: WS_PORT
});
wss.on('connection', function (ws) {
// ws.send(JSON.stringify(message));
setInterval(function () {
updateXData(ws)
}, 500);
});
function updateXData(ws) {
var newMessage = {
"data": ""
}
newMessage.data = message.data
ws.send(JSON.stringify(newMessage));
}
So the question is: Is there a cleaner way to do this just by using ws to handle the data from the WiFly and then sending it to the client?
Thanks in advance!
Not sure whether this will suit you and might be new to you but you could make use of MQTT, there are free brokers available which are very good and its relatively easy to set up and implement with Arduino equipped with WiFly Shield.
http://mqtt.org/
Hope this helps somewhat!