NodeJs Convert 'net' socket to SSL/TLS based socket? - javascript

I have following nodejs code running on the server (chat engine). I want to convert this into a secure SSL/TLS based connection. How do i do that ?
In the client side (see below code), everytime i tried to convert this into SSL it gives me a error of "Cross origin request failed." i dont know why ?
NODE.JS Server Side Code
var cluster = require('cluster');
var net = require('net');
var fs = require('fs');
var config = require('./config.js');
var num_processes = 1;//require('os').cpus().length;
if (cluster.isMaster) {
// This stores our workers. We need to keep them to be able to reference
// them based on source IP address. It's also useful for auto-restart,
// for example.
var workers = [];
// Helper function for spawning worker at index 'i'.
var spawn = function (i) {
workers[i] = cluster.fork();
// Optional: Restart worker on exit
workers[i].on('exit', function (worker, code, signal) {
if (config.server.restart_instances_on_crash) {
spawn(i);
logging.log('debug', 'Node instances exited, respawning...');
}
});
};
// Spawn workers.
for (var i = 0; i < num_processes; i++) {
spawn(i);
}
// Helper function for getting a worker index based on IP address.
var worker_index = function (ip, len) {
var s = '';
for (var i = 0, _len = ip.length; i < _len; i++) {
if (ip[i] !== '.') {
s += ip[i];
}
}
return Number(s) % len;
};
/* wait 5 seconds to make sure all the instances are running and initialized */
setTimeout(function () {
// Create the outside facing server listening on our port.
var options = {
pauseOnConnect: true
};
var server = net.createServer(options, function (connection) {
// We received a connection and need to pass it to the appropriate
// worker. Get the worker for this connection's source IP and pass
// it the connection.
var str = connection.remoteAddress;
var ip = str.replace("::ffff:", '');
var worker = workers[worker_index(ip, num_processes)];
worker.send('sticky-session:connection', connection);
}).listen(config.server.listenport);
logging.log('debug', 'Server listening on ' + config.server.listenip + ':' + config.server.listenport + '...');
}, 5000);
process.on('uncaughtException', function (error) {
logging.log('error', 'uncaughtException');
logging.log('error',error.stack);
process.exit(1);
});
} else {
var express = require('express');
var sio = require('socket.io');
var sio_redis = require('socket.io-redis');
var dateandtime = require('./includes/dateandtime.js');
var stats = require('./includes/stats.js');
var helper = require('./includes/helper.js');
// Note we don't use a port here because the master listens on it for us.
var app = new express();
// Don't expose our internal server to the outside.
var server = app.listen(0, 'localhost'),
io = sio(server);
io.set('origins', '*:*');
}
In my Client side i have following code based socket.io JS module. (All these works fine without the SSL connection when using net module only)
Following is the client side javascript code to connect to the node server using socket.io functions.
var root_url = 'http://'+window.location.hostname;
var socket_io = 'http://example.com/js/chat/socket.io-1.3.5.js';
$(document).ready(function () {
$.getScript(socket_io, function () {
socket = io.connect(root_url + ':8440');
... etc

Can only hint you into checking the cors package for crossdomain requests but the deeper issue could be that not everything is running in SSL. (mixed http & https)

Related

Cannot connect or emit to Amazon ECS Socket.io Server via Socket.io from a HTML file located in S3 bucket

I am having trouble connecting and emitting to an ECS Fargate Socket.io Server on AWS via Socket.io from a HTML file located in a S3 bucket in the same AWS region.
The ECS Fargate Server's code is as follows:
var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);
var AWS = require ('aws-sdk');
io.on('connect', function (socket){
console.log('connection made');
socket.on('disconnect', function (socketds) {
console.log("***********************************************");
console.log("Disconnected");
});
socket.on('reconnect', function (socketds) {
console.log("***********************************************");
console.log("Reconnected");
});
socket.on('c_status', function () {
console.log("*********************************************");
console.log("cstatus");
});
socket.on('app_message', function (mdata) {
console.log("***********************************************");
console.log("App-message:",mdata);
socket.emit('command1',mdata);
});
});
http.listen(3000, function () {
console.log('listening on *:3000');
});
And the relevant code of the HTML file is as follows:
<script>
const serverLocation = "http://application-load-balancer-dns-link:3000";
const socket = io(serverLocation);
function sendmsg() {
var date = new Date();
date.setHours(date.getHours() + 4);
var datetm = date.toISOString().split('.')[0]+"Z";
var node_id = $('#innode').val();
var clid = "0";
var msg = $('#message').val();
if (node_id.length === 1) {
var unitcode = "0" + "0" + node_id;
}
else if (node_id.length === 2) {
var unitcode = "0" + node_id;
}
else {
var unitcode = node_id;
}
var mdata = datetm+unitcode+msg;
socket.emit('app_message',mdata);
}
</script>
I have been at it for 2 days now and have not been able to figure it out. It just doesn't connect.
Any help is greatly appreciated.
If you need more information, please let me know.
1) Try checking the inbound rules of the security group associated with that instance.
2) Outbound rules should also be configured as its bidirectional (By Default allows all)
3) If they are perfect. Check whether timeout occurs or any other exception.

Problems multithreading with cluster on Node.JS(Express + socket.io)

Here is the guide I'm basing my code off of: https://github.com/elad/node-cluster-socket.io
Although 9 threads are started, only one is in use at a time, and it's always the same thread that gets used. Their code works fine, but I've modified it to work with my program, and that's where I'm having issues.
manager.js:
var express = require('express'),
cluster = require('cluster'),
net = require('net'),
sio = require('socket.io'),
sio_redis = require('socket.io-redis');
var port = 3000,
num_processes = require('os').cpus().length;
if (cluster.isMaster) {
// This stores our workers. We need to keep them to be able to reference
// them based on source IP address. It's also useful for auto-restart,
// for example.
var workers = [];
// Helper function for spawning worker at index 'i'.
var spawn = function(i) {
workers[i] = cluster.fork();
// Optional: Restart worker on exit
workers[i].on('exit', function(code, signal) {
console.log('respawning worker', i);
spawn(i);
});
};
// Spawn workers.
for (var i = 0; i < num_processes; i++) {
spawn(i);
}
// Helper function for getting a worker index based on IP address.
// This is a hot path so it should be really fast. The way it works
// is by converting the IP address to a number by removing non numeric
// characters, then compressing it to the number of slots we have.
//
// Compared against "real" hashing (from the sticky-session code) and
// "real" IP number conversion, this function is on par in terms of
// worker index distribution only much faster.
var worker_index = function(ip, len) {
var s = '';
for (var i = 0, _len = ip.length; i < _len; i++) {
if (!isNaN(ip[i])) {
s += ip[i];
}
}
return Number(s) % len;
};
// Create the outside facing server listening on our port.
var server = net.createServer({ pauseOnConnect: true }, function(connection) {
// We received a connection and need to pass it to the appropriate
// worker. Get the worker for this connection's source IP and pass
// it the connection.
var worker = workers[worker_index(connection.remoteAddress, num_processes)];
worker.send('sticky-session:connection', connection);
}).listen(port);
} else {
// Note we don't use a port here because the master listens on it for us.
var server_local = require('./server.js');
server_local.startServer(0, function(server, io) {
// Here you might use middleware, attach routes, etc.
// Don't expose our internal server to the outside.
// Tell Socket.IO to use the redis adapter. By default, the redis
// server is assumed to be on localhost:6379. You don't have to
// specify them explicitly unless you want to change them.
io.adapter(sio_redis({ host: 'localhost', port: 6379 }));
// Here you might use Socket.IO middleware for authorization etc.
// Listen to messages sent from the master. Ignore everything else.
process.on('message', function(message, connection) {
if (message !== 'sticky-session:connection') {
return;
}
// Emulate a connection event on the server by emitting the
// event with the connection the master sent us.
server.emit('connection', connection);
connection.resume();
});
});
}
server.js:
var fs = require('fs');
var satJS = require('satellite.js');
var express = require('express');
var app = new express();
var serv = require('http').Server(app);
var sio = require('socket.io');
...
exports.startServer = function(port, callback) {
updateSatelliteData(function() {
server = app.listen(port);
io = sio(server);
initalize(io);
callback(server, io);
console.log("Server started");
});
}
function initalize(io) {
//Web stuff
app.get('/', function(req, res) {
res.sendFile(__dirname + '/client/index.html');
});
app.use('/client', express.static(__dirname + '/client'));
io.sockets.on('connection', function(socket) {
...
}
etc.
}

Bug in sending multiple 2-D Arrays through socket.io

I am noticing a bug in socket.io. I am sending multiple (5) 2-D Array's through socket.io. All of the Array's are coming through, at different lengths/sizes and at different times, if that matters with how node.js or socket.io handle them. But they are seperate so I didn't think it mattered, just mentioning.
I have the incoming data from another source that populates Array1, Array2....ect. Here are some examples of what's happening, when sending through socket.io.
When I send test1: test1 does populate on the client side.
When I send test2: test2 does not populate on the client side.
when I send test2, then test1: test1 and test2 populate on the client side.
var Array1 = [];
var Array2 = [];
var Array3 = [];
var Array4 = [];
var Array5 = [];
jsonResults = JSON.stringify({
'test1': Array1,
'test2': Array2,
'test3': Array3,
'test4': Array4,
'test5': Array5
});
Just for an example of how I am calling variables on the client side
var socket = io.connect();
socket.on('message', function(message){
var obj = jQuery.parseJSON(message);
var value1 = obj.test1[1][1];
var value2 = obj.test2[0][5];
I have another question, If on the client side I call out a variable that doesn't exist like obj.test1[5][5] when test1 is only [4,5] sometimes it doesn't populate on the client side, for all the variables like test1[1][1] which does exist; Is there a particular reason for this or am I approaching this wrong?
Is there a better way to program this from .js side I have to handle multiple 2-D arrays of unknown size coming in at different times.
Server Side Listening to outside traffic.
// start UDP server listening on port 3001
udpRunningResultsServer.on("listening", function () {
var address = udpRunningResultsServer.address();
console.log("UDP Running Results Server listening on port: " + address.port);
console.log(" ")
});
udpRunningResultsServer.bind(3001);
// process datagram
udpRunningResultsServer.on("message", function (Runningmsg, Runninginfo) {
// check if datagram is full (size=536)
if(Runninginfo.size == 536){
tempRunningResults = tempRunningResults + Runningmsg.toString();
}
// datagram is not full, so this is the end of the message
else{
finalRunningResults = tempRunningResults + Runningmsg.toString();
RunningArray = finalRunningResults.split(';');
for (var a = 0; a < RunningArray.length; a++) {
var Runningtmp = RunningArray[a].length;
if (Runningtmp == 14 || Runningtmp == 0){
RunningArray.splice(a,1);
}
else {
RunningArray[a]= RunningArray[a].split(',');
}
}
RunningArray.unshift(time);
tempRunningResults ='';
}
});
// start UDP server listening on port 3002
udpShotPutWeightThrowResultsServer.on("listening", function () {
var address = udpShotPutWeightThrowResultsServer.address();
console.log("UDP Shotput/Weight Throw Server listening on port: " + address.port);
console.log(" ")
});
udpShotPutWeightThrowResultsServer.bind(3002);
// process datagram
udpShotPutWeightThrowResultsServer.on("message", function (ShotputWeightThrowmsg, ShotputWeightThrowinfo) {
tempShotputWeightThrowResults = ShotputWeightThrowmsg.toString();
finalShotputWeightThrowResults = finalShotputWeightThrowResults+tempShotputWeightThrowResults;
finalShotputWeightThrowResults = finalShotputWeightThrowResults.trim()
console.log(finalShotputWeightThrowResults);
//if (tempShotputWeightThrowResults == '~'){
console.log(finalShotputWeightThrowResults);
ShotputWeightThrowArray = finalShotputWeightThrowResults.split(';');
for (var a = 0; a < ShotputWeightThrowArray.length; a++) { =
ShotputWeightThrowArray[a]= ShotputWeightThrowArray[a].split(',');
}
var serv_io = io.listen(htmlServer, { log: false });
serv_io.sockets.on('connection', function(socket){
//send data to client
setInterval(function(){
jsonResults = JSON.stringify({
'runningobj': ShotputWeightThrowArray,
'shotputweightthrowobj': RunningArray,
'longtriplejumpobj': LongTripleJumpArray,
'highjumpobj': HighJumpArray,
'polevaultobj': PoleVaultArray
});
console.log(jsonResults);
socket.send(jsonResults);
}, 1000);
});
Here is an example of what is coming through the socket.
{"runningobj":["0.0",["UNOFFICIAL","Decat Men 110 Meter Hurdles","nwi","41","6","4","041-6-04","AUTO","4"],["","2","504","Klaus Ambrosch","Arizona","","","","","","","","","",""],["","4","693","Troy McDonough","Montana","","","","","","","","","",""],["","6","818","Pat Buckheit","Tennessee","","","","","","","","","",""],["","8","746","James Cook","Penn State","","","","","","","","","",""],",,,,,,,,,,,,,,",",,,,,,,,,,,,,,",",,,,,,,,,,,,,,",",,,,,,,,,,,,,,",",,,,,,,,,,,,,,",",,,,,,,,,,,,,,",",,,,,,,,,,,,,,",",,,,,,,,,,,,,,",",,,,,,,,,,,,,,",",,,,,,,,,,,,,,",["\u0003\u0004"]],"shotputweightthrowobj":[["\u0001R\u0002Unofficial","HammerThrowWomen","","19","1","1","019-1-01",""],["1","1","79","Crozier","Unattached","33.55","","110'01\""],["~"],["","","","","","","",""],["~"],["","","","","","","",""],["~"],["","","","","","","",""],["~"]],"longtriplejumpobj":[],"highjumpobj":[],"polevaultobj":[]}

running node.js http server on multiple ports

Please can anybody help me to find out how to get the server socket context in node.js, so that i will come to know request came on which port number on my server.
I can read the server port if i request using http headers but I want it through network and something like socket context which tells request came on which port number.
Here is the sample code:
var http=require('http');
var url = require('url');
var ports = [7006, 7007, 7008, 7009];
var servers = [];
var s;
function reqHandler(req, res) {
var serPort=req.headers.host.split(":");
console.log("PORT:"+serPort[1]);//here i get it using http header.
}
ports.forEach(function(port) {
s = http.createServer(reqHandler);
s.listen(port);
servers.push(s);
});
The req object has a reference to the underlying node socket. You can easily get this information as documented at: http://nodejs.org/api/http.html#http_message_socket and http://nodejs.org/api/net.html#net_socket_remoteaddress
Here is your sample code modified to show the local and remote socket address information.
var http=require('http');
var ports = [7006, 7007, 7008, 7009];
var servers = [];
var s;
function reqHandler(req, res) {
console.log({
remoteAddress: req.socket.remoteAddress,
remotePort: req.socket.remotePort,
localAddress: req.socket.localAddress,
localPort: req.socket.localPort,
});
}
ports.forEach(function(port) {
s = http.createServer(reqHandler);
s.listen(port);
servers.push(s);
});

Node.js, multi-threading and Socket.io

I'm looking to get Socket.io to work multi-threaded with native load balancing ("cluster") in Node.js v.0.6.0 and later.
From what I understand, Socket.io uses Redis to store its internal data. My understanding is this: instead of spawning a new Redis instance for every worker, we want to force the workers to use the same Redis instance as the master. Thus, connection data would be shared across all workers.
Something like this in the master:
RedisInstance = new io.RedisStore;
The we must somehow pass RedisInstance to the workers and do the following:
io.set('store', RedisInstance);
Inspired by this implementation using the old, 3rd party cluster module, I have the following non-working implementation:
var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
// Fork workers.
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
var sio = require('socket.io')
, RedisStore = sio.RedisStore
, io = sio.listen(8080, options);
// Somehow pass this information to the workers
io.set('store', new RedisStore);
} else {
// Do the work here
io.sockets.on('connection', function (socket) {
socket.on('chat', function (data) {
socket.broadcast.emit('chat', data);
})
});
}
Thoughts? I might be going completely in the wrong direction, anybody can point to some ideas?
Actually your code should look like this:
var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
// Fork workers.
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
} else {
var sio = require('socket.io')
, RedisStore = sio.RedisStore
, io = sio.listen(8080, options);
// Somehow pass this information to the workers
io.set('store', new RedisStore);
// Do the work here
io.sockets.on('connection', function (socket) {
socket.on('chat', function (data) {
socket.broadcast.emit('chat', data);
})
});
}
Another option is to open Socket.IO to listen on multiple ports and have something like HAProxy load-balance stuff.
Anyway you know the most important thing: using RedisStore to scale outside a process!
Resources:
http://nodejs.org/docs/latest/api/cluster.html
How can I scale socket.io?
How to reuse redis connection in socket.io?
Node: Scale socket.io / nowjs - scale across different instances
http://delicious.com/alessioaw/socket.io

Categories

Resources