nodejs cluster socket.io express app - javascript

var httpsport = 8080, // used for httpsapp
httpport = 8000, // used for httpapp
numCPUs = require('os').cpus().length;
var credentials = {
key: fs.readFileSync('./cert/client.key'),
cert: fs.readFileSync('./cert/client.crt'),
requestCert: true
};
var cluster = require('cluster'),
socketStore = require('socket.io-clusterhub');
var redis = require('redis');
var redisClient = redis.createClient();
if(cluster.isMaster) {
for(var i=0; i<numCPUs; i++) {
cluster.fork();
}
} else {
var io = require('socket.io'),
express = require('express'),
httpsapp = express(), // for https services
httpapp = express(), // for http services
http = require('http'),
https = require('https');
httpapp.configure( function () {
httpapp.use(express.bodyParser());
httpapp.use(express.methodOverride);
httpapp.use(httpapp.router);
httpapp.set('port', httpport);
httpapp.use(express.static(__dirname+'/public', {maxAge:oneDay}));
});
httpsapp.configure( function() {
// allow CORS
httpsapp.all('*', function(req, res, next){
if(!req.get('Origin')) {
return next();
}
// use "*" here to accept any origin
res.set('Access-Control-Allow-Origin', '*');
res.set('Access-Control-Allow-Methods', 'GET');
res.set('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type');
// res.set('Access-Control-Allow-Max-Age', 3600);
if ('OPTIONS' === req.method) {
return res.send(200);
}
next();
});
httpsapp.use(express.bodyParser());
httpsapp.use(express.static(__dirname + '/public'));
httpsapp.set('port', httpsport);
});
var httpServer = http.createServer(httpapp),
httpsServer = https.createServer(credentials, httpsapp),
sio = io.listen(httpServer);
// set the configuration for production.
sio.configure('production', function(){
sio.enable('browser client etag');
sio.set('log level', 1);
sio.set('store',socketStore);
sio.set('transports', [
'websocket',
'flashsocket',
'htmlfile',
'xhr-polling',
'jsonp-polling'
]);
});
sio.of('/namespace1').on('connection', function(socket) {
socket.on('doSomething', function() {
socket.emit('reply',{hello:world}) });
httpsapp.get("/user", function(req, res) {
// ...
});
}
}
If node cluster is used, I'm getting the response: Cannot GET /user. But without cluster, it is able to service the https.get("/user").
Also, using cluster, I would like to check if the redis, http(s), socket.io and express module should be declare in the workers part or declare globally?
The httpsapp.get() is nested within the socket space because it would want to reply to the specific socket. Is there any way to get around this structure?
Anyone could figure our why httpsapp.get() is not servicing request?
And also where would those declaration be appropriate?
Thank you!

Related

jaeger endpoint isnt recieving data using jaeger Node.js client

Was trying to connect to jaeger using HTTP request using nodejs but the spans are not reaching the jaeger endpoint. please help with this code snippet.,
var initTracer = require('jaeger-client').initTracer;
var config = {
'serviceName': 'servicename1',
'reporter': {
'collectorEndpoint': 'http://jaeger-collector:14268/api/traces',
}
};
var options = {
tags: {
'servicename1': '1.0'
}
};
var tracer = initTracer(config, options);
var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app);
app.get('/', (req, res) => {
const span = tracer.startSpan('http_request');
res.send('Hello Jaeger');
span.log({'event': 'request_end'});
span.finish();
});
app.get('/', function(req, res) {
res.send("Hello World!");
});
server.listen(3000);
console.log('Express server started on port %s', server.address().port);
Any help would be much appreciated!
Got it! We need to enable sampling strategy to reach the collector endpoint.
var initTracer = require('jaeger-client').initTracer;
var config = {
'serviceName': 'Jaeger_Service',
'reporter': {
'collectorEndpoint': 'http://jaeger-collector:14268/api/traces',
},
'sampler': {
'type': 'const',
'param' : 0.1
}
};
var options = {
'logger': {
'info': function logInfo(msg) {
console.log('INFO ', msg)
},
'error': function logError(msg) {
console.log('ERROR', msg)
}
}
};
var tracer = initTracer(config, options);
var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app);
app.get('/', (req, res) => {
const span = tracer.startSpan('http_request');
res.send('Hello Jaeger');
span.log({'event': 'request_end'});
span.finish();
});
server.listen(8000);
console.log('Express server started on port %s', server.address().port);

Socket.IO 404 works locally but not when deployed via Netlify

Socket.IO works locally but not when deployed via Netlify
Please excuse my code, i'm a newbie to node.js etc.
This is the error I get:
Failed to load resource: the server responded with a status of 404 () (socket.io, line 0)
Client:
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.dev.js"></script>
function syncObj() {
var socket = io.connect()
socket.emit('sync', `${objId}`)}
// Listen for events
function syncComplete() {
var socket = io.connect()
socket.on('sync', function (data) {
objId = data
noti5()
document.getElementById("note4").style.display = "none";
document.getElementById("note6").style.display = "none";
// What do do when sync is complete
// Say Something
// Refresh Screen
})
}
//Server:
const express = require('express');
const opn = require('opn');
const app = express();
const port = 5000
var socket = require('socket.io')
const cors = require("cors")
function allowCrossDomain(req, res, next) {
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Methods', 'PUT, POST, PATCH, DELETE, OPTIONS');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next()}
app.use(allowCrossDomain)
app.use(cors())
app.use('/', express.static(__dirname + '/public'))
var server = app.listen(port, function () {
console.log('listening to request on port 5000');
opn(`http://localhost:${port}`);
});
// Socket Setup
var io = socket(server);
io.on('connection', function (socket) {
console.log('made socket connection', socket.id)
socket.on("sync", function(data){
io.sockets.emit('sync', data)
})
})
Worked perfectly locally. Please help.
You should mention your url in the io.connect(url here)
try this:
var socket = io('/');
If we put '/' instead of url it will automatically take the url if it is localhost or hosted on other ip.You can also mention your full url here like this.
var socket = io('http://localhost:port')
//or something else
Here is an example:
server:
const express = require('express');
const app = express();
const socket = require('socket.io');
const port = process.env.PORT || 8080;
//starting the server
const server = app.listen(port,() => {console.log("server running")});
//connecting socket to the server
const io = socket(server);
io.set('transports', ['websocket']);
io.on('connection',socket =>{
// your code here
}
client:
var socket = io('/',{transports: ['websocket'],upgrade:false});
//on connection
socket.on('connect',data =>{
//logic here
}

Enabling HTTPS on an express server

I'm trying to configure my express server to use HTTPS but I am running into some issues. I followed the documentation to setup my HTTPS server but I am still encountering some errors.
Here's my app.js
var express = require('express');
var app = express();
var server = require('https').createServer(options, app);
var io = require('socket.io')(server);
var port = process.env.PORT || 3000;
var fs = require('fs');
var options = {
key: fs.readFileSync('/test/key.pem'),
cert: fs.readFileSync('/test/cert.pem')
};
server.listen(port, function () {
console.log('Server listening at port %d', port);
});
When starting my server I encounter
https.js:32
if (process.features.tls_npn && !opts.NPNProtocols) {
^
TypeError: Cannot read property 'NPNProtocols' of undefined
at new Server (https.js:32:40)
at Object.exports.createServer (https.js:56:10)
So, I tried to define NPNProtocols within options, but that did not work. Anyone have any pointers here?
Thank you.
try this once, i think you should have certificate in .crt format. and you will require tls module.
var sslOptions = {
key: fs.readFileSync('public/server.key'),
cert: fs.readFileSync('public/server.crt')
};
tls.createServer(sslOptions, function (cleartextStream) {
var cleartextRequest = net.connect({
port: port,
host: serverStr
}, function () {
cleartextStream.pipe(cleartextRequest);
cleartextRequest.pipe(cleartextStream);
});
}).listen(443);
port is you http port . and sercerStr is you server address.
IMO, the issue is not with the extension of the keys, rather the ssl configuration used. Use https node module with correct ssl options for ca, cert, and key to enable https with express.
// server/index.js
const express = require('express');
const fse = require('fs-extra');
const helmet = require('helmet');
const https = require('https');
const path = require('path');
// path to cert files
const paths = {
certFile: '/path/to/cert.pem',
chainFile: '/path/to/fullchain.pem',
privateFile: '/path/to/privkey.pem',
};
/* Express implementation (ignore) */
const app = express();
app.use(helmet());
app.use(express.static(path.join(__dirname, '..')));
app.get('/', (request, response) => {
response.sendFile(path.join('index.html'));
});
// setup https
const setupHttps = () => {
const promises = [
fse.readFile(paths.chainFile),
fse.readFile(paths.privateFile),
fse.readFile(paths.certFile),
];
return Promise
.all(promises)
.then(data => {
const [ chainData, privateData, certData ] = data;
const options = {
ca: chainData.toString('utf-8'),
cert: certData.toString('utf-8'),
key: privateData.toString('utf-8'),
};
return https.createServer(
options,
app
).listen(443);
})
.catch(err => console.log(err));
};
return setupHttps();
EDIT: I used helmetjs for better security with http headers.

Checking CA in socket.io-client

I have created an HTTPS server with socket.io and a client with socket.io-client.
Problem is that apparently socket.io-client does not check validity of HTTPS connection by the given CA in it's option.
For clarification here's a sample code: In simple https request if I do not provide CA in client I get Error: unable to verify the first certificate, but with socket.io-client connection establishes, which is totally not what I want.
//Client
var https = require('https'),
socketClient = require('socket.io-client'),
fs = require('fs');
var options = {
// IT'S EXPECTED THAT I DON'T PROVIED CA, HTTPS CONNECTION FAILS
//ca: fs.readFileSync('cert/ca.crt'),
agent: false
};
var socket = socketClient('https://localhost', options);
socket.on('connect', function() {
console.log('Connected to hub');
socket.emit('msg', function(resp){
console.log('Response: ' + resp);
});
});
And server :
// Server
var https = require('https'),
socketIo = require('socket.io'),
fs = require('fs');
var options = {
// CERTIFICATE HAS BEEN SIGNED WITH CA
cert: fs.readFileSync('cert/signed.crt'),
key: fs.readFileSync('cert/signed.key'),
rejectUnauthorized: false
};
var app = https.createServer(options, function(req, res) {
res.end('Hi');
});
var io = socketIo(app);
io.on('connection', function(socket) {
console.log('Connected !');
socket.on('msg', function(cb) {
console.log('Msg recved');
cb('Client got it');
});
});
app.listen(443, function() {
console.log('Server Started ...');
});

how to make redis session store available in socket.io

I am using node.js with socket.io and redisStore for my express-sessions. on my socket handshake, i want to read the cookie to get the session cookie, so i am able to read from and write to the session.
here is what i got so far:
in my app.js:
var express = require('express');
var app = express();
var redis = require('redis');
var redisClient = redis.createClient(6379, 'localhost');
server = http.createServer(app);
server.listen(8080, function() {
console.log('listening on *:8080');
});
var io = require('./routes/index').listen(server);
var routes = require('./routes/index').router;
app.use(session({
secret: 'my-secret-string',
key: 'express.sid',
cookie: { maxAge: 2628000000 },
store: new (require('express-sessions'))({
storage: 'redis',
instance: redisClient,
host: 'localhost',
port: 6379,
}),
resave: true,
saveUninitialized: true
}));
app.use('/', routes);
module.exports = app;
and in my index.js:
var express = require('express');
var router = express.Router();
var socketio = require('socket.io');
var io;
router.get('/', function(req, res) {
//do stuff here...
res.render('index', { params: params });
}
var listen = function(app) {
io = socketio.listen(app);
io.sockets.on('connection', function (socket) {
console.log(socket.handshake); // there is an handshake object with cookie information
// which i can parse the express.sid (=sessionID) from
socket.on('someEvent', function(args, callback) {
//do stuff here
callback(err, msg);
});
});
return io;
}
module.exports = {
listen: listen,
router: router
}
Now, when the client emits "someEvent", i want to read the session ID from the session cookie and do stuff with the session data.
I followed this guide, and this, but they seem to be outdated or do not fit quite my setup.
Had have no luck so far. Help is greatly appreciated! This is my first node.js project..

Categories