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 ...');
});
Related
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);
I have two applications hosted in openshift v2, both have the same code, the first uses Node.js 0.10 and socket.io works perfectly. The second application uses Node.js 8.2.1 but socket.io doesn't work and I get the same error as in these other sites:
Client side receive polling on socket.io
Socket.io cannot connect, resorts to “polling”
Socket.io connection reverts to polling, never fires the 'connection' handler
I tried to make the answers, but without result, if the code is the same in my two applications.. What can be failing? It's necessary to make some changes in the new version of Node.js?
This is the relevant code in my application and information about it:
Both app run perfectly on ports 8080 or 3000.
SERVER
App.js
var fs = require('fs');
var express = require('express');
var app = express();
var server = require('http').Server(app);
var bodyParser = require ('body-parser');
var jwt = require('jsonwebtoken');
var io = require('socket.io')(server);
var server_ip_address = process.env.OPENSHIFT_NODEJS_IP || '127.0.0.1';
var server_port = process.env.OPENSHIFT_NODEJS_PORT || 3000;
server.listen(server_port, server_ip_address, function () {
console.log( "APP Listening on: " + server_ip_address + ":" + server_port )
});
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static(__dirname + '/'));
app.get('/', function (req, res) {
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function (socket) {
console.log('USUARIO CONECTADO');
socket.on('coordenada', function (data) {
io.emit('notificacion', {
Latitud: data.latitudData,
Longitud: data.longitudData,
Nombre: data.name
});
});
});
CLIENT
Controllers.js
app.controller('mapCtrl', function ($scope, NgMap, socket) {
vm = this;
socket.on('notificacion', function(data) {
console.log("coordenada recibida: ", data.Latitud +","+ data.Longitud +" de "+ data.Nombre);
var name = data.Nombre;
vm.transportistas = [
{id:'1', nombre: data.Nombre, posicion:[data.Latitud, data.Longitud]}
];
NgMap.getMap().then(function(map) {
vm.map = map;
google.maps.event.trigger(vm.map, 'resize');
});
});
vm.wayPoints = [
{location: {lat:39.502223, lng: -0.363244}},
];
NgMap.getMap()
.then(function(map) {
vm.map = map;
vm.map.setZoom(6);
vm.map.setCenter(new google.maps.LatLng(40, -4));
});
vm.mostrarDetalles = function(e, transportista) {
vm.transportista = transportista;
vm.map.showInfoWindow('foo-iw', transportista.id);
};
});
factorias.js
app.factory('socket', ['$rootScope', function($rootScope) {
var socket = io.connect();
return {
on: function(eventName, callback){
socket.on(eventName, callback);
},
emit: function(eventName, data) {
socket.emit(eventName, data);
}
};
}]);
And I get this on web console ONLY in the app with Node.js 8.2.1:
GET http://localhost/socket.io/?EIO=3&transport=polling&t=1448850081140-15
GET http://localhost/socket.io/?EIO=3&transport=polling&t=1448850080247-12
GET http://localhost/socket.io/?EIO=3&transport=polling&t=1448850080252-13
etc...
**I'm sorry for my English.
I am not really sure how to send and receive data using socket.io rooms.
This is my client side code:
var socket = io('https://the.url');
socket.on('connect', function() {
console.log('Connected to the socket.');
});
socket.on("client5", function (data) {
console.log(data);
});
And this is my server side code
var app = require('express')();
var server = require('http').Server(app);
var https = require('https');
var fs = require('fs');
var bodyParser = require('body-parser');
var privateKey = fs.readFileSync('path/to/key', 'utf8');
var certificate = fs.readFileSync('path/to/key', 'utf8');
var credentials = {key: privateKey, cert: certificate};
var httpsServer = https.createServer(credentials, app);
var io = require('socket.io')(httpsServer);
// HTTP server listening on port
io.set('origins', '*:*');
io.sockets.on('connection', function (socket) {
});
httpsServer.listen(10000);
// Middle ware
app.use(bodyParser.urlencoded({ extended: true }));
// Route
app.post('/anything', function (req, res) {
io.emit('client5', req.body);
res.end();
});
And this works fine. But this is not using the rooms. This code will just emit data to "client5" socket and on the client side I am able to receive that data using socket.on("client5").
What I want to do is have a group of people that will be joining different rooms.
So user A, B and C will come in and be added to room "First Room" and users D, E and F will be added to "Second Room".
How can I send and receive data between rooms?
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!
I am trying to build a small app in nodejs to publish and subscribe. I am stucked in how I can publish from client side. Here is the code I have.
Here is my server code (server.js)
var express = require('express'),
app = express(),
http = require('http'),
server = http.createServer(app);
app.use(express.bodyParser());
app.get('/', function(req, res) {
res.sendfile(__dirname + '/public/index.html');
});
app.post('/publish/:channel/:event/', function(req, res) {
console.log("**************************************");
var params = req.params;
console.log(req.params);
console.log(req.body);
var data = req.body;
console.log("**************************************");
var result = io.sockets.emit(params.channel,{event:params.event,data:data});
//console.log(result);
console.log("**************************************");
res.sendfile(__dirname + '/public/index.html');
});
//include static files
app.use(express.static(__dirname + '/public'));
server = server.listen(3000);
var io = require('socket.io').listen(server);
io.sockets.on('connection', function (s) {
socket = s
socket.emit('c1', { hello: 'world' });
socket.on('test', function (data) {
socket.emit('c1', { hello: 'world' });
console.log('test');console.log(data);
});
});
And here is client code
var narad = {};
narad.url = 'http://192.168.0.46:3000';
narad.lisentingChannels = {}
var socket = io.connect(narad.url);
function Channel(channelName) {
this.channelName = channelName; //serviceObject is the object of
this.events = {};
};
Channel.prototype.bind = function (event, callback) {
this.events[event] = callback;
};
narad.subscribe = function (channelName) {
var channel = new Channel(channelName)
this.lisentingChannels[channelName] = channel;
socket.on(channelName, this.callbackBuilder(channel))
return this.lisentingChannels[channelName];
}
narad.callbackBuilder = function (channel) {
return function (data) {
var callback = channel.events[data["event"]];
callback(data.data);
}
}
You can use the emit method on both the client and the server websocket connections, taken from Socket.io:
var socket = io.connect(narad.url);
socket.emit('publish', 'message');
Then on your server you listen for the message:
socket.on('publish', function (data) {
// Emit the published message to the subscribers
socket.emit('subscribers', data);
console.log(data);
});
This way you are using the bi-directional communication of websockets without having to use some POST api.