node, socket.io - authorization fail - node.js

This is a skeleton of my app.js file.
What I don't understand is way it doesn't read and print "log authorisation".
I followed this https://github.com/LearnBoost/socket.io/wiki/Authorizing
var express = require('express');
mongoose = require('mongoose');
var MongoStore = require('connect-mongo')(express);
app = express();
// costants
var SITE_SECRET = 'xxx';
// mongoose
mongoose.connect('mongodb://127.0.0.1/test');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function callback () {
console.log('Mongoose connection is now opened');
});
// pass same objects from Express to Socket.IO so they match
var parseCookie = express.cookieParser(SITE_SECRET);
var store = new MongoStore({
mongoose_connection: mongoose.connection,
db: mongoose.connections[0].db
});
app.configure(function(){
app.set('host', '127.0.0.1');
app.set('port', 1111);
// init cookie-session
app.use(parseCookie);
app.use(express.session({
secret : SITE_SECRET
,store : store
,cookie: { maxAge: new Date(Date.now() + (1000*60*60*24*30*12)) }
}));
});
// create and start server
var server = require('http').createServer(app)
server.listen(app.get('port'));
// socket.io
var io = require('socket.io').listen(8080);
io.configure(function() {
console.log('log configure <-- it read this. ok!');
io.set('authorization', function(handshake, callback) {
console.log("log authorisation <-- but it doesn't read this. why??");
if (handshake.headers.cookie) {
parseCookie(handshake, null, function() {
handshake.sessionID = handshake.signedCookies['connect.sid'];
store.get(handshake.sessionID, function(err, session) {
callback(null, true);
});
});
} else {
// they client has no session yet, don't let them connect
callback('No session.', false);
}
});
});
clients = {};
io.sockets.on('connection', function (socket) {
// save to a global object
console.log('save session');
var session = socket.handshake.sessionID;
clients[session] = socket;
socket.on('disconnect', function() {
console.log('remove session');
delete clients[session];
});
});
// routes
app.get('/on', function(req, res){
var socket = clients[req.sessionID];
socket.on('test', function (data) {
console.log(data);
});
});
app.get('/emit', function(req, res){
var socket = clients[req.sessionID];
socket.emit('test', "ciao");
console.log("emit");
});
when I start the server on the terminal I see this:
starting `node app.js`
Mongoose connection is now opened
info - socket.io started
log configure
And if I load the page "/on"
the error is:
TypeError: Cannot call method 'on' of undefined
I'm stack here from too much... What's wrong in this?
Maybe someone had the same problem...

try making socket.io listen to server port, you define 1111 as a port for server and 8080 for socket.io , you application is available for access at localhost:1111.
short example
var server = http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
io.listen(server);

Related

Socket.io emit not working (by visiting URL)

I am developing an app that gets a signal from external hardware equipment. I catch this signal by redirecting it to a certain URL in my app: '/impulse/:id'.
I am able to catch the signal, but the emit function inside the app.get('/impulse/:id') is not triggering. The console logs are...
How can I make the emit function work?
Below is my server.js script, where I catch all the socket signals and prevent the external call from being redirected to the index page.
...
const express = require('express');
const app = express();
const port = process.env.PORT || 8080;
const socket = require('socket.io');
app.use(express.static(__dirname + '/public'));
app.use('/api', appRoutes);
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://HERE IS MY DB INFO...', function(err) {
if (err) {
console.log('Not connected to the database: ' + err); // Log to console if unable to connect to database
} else {
console.log('Successfully connected to MongoDB'); // Log to console if able to connect to database
}
});
var server = app.listen(port, function() {
console.log('Running the server on port ' + port); // Listen on configured port
});
var io = socket(server);
io.on('connection', function(socket){
socket.on('join', function(data){
var gameroom = data.gameid;
console.log("joined: " + gameroom)
socket.join(gameroom);
})
//FUNCTION I WANT TO TRIGGER
socket.on('impulse', function(data){
console.log('IMPULSE')
io.emit('impulseReceived', {
})
})
})
//PLACE WHERE I EMIT
app.get('/impulse/:id', function(req, res){
console.log('Impulse Received')
var time = req.query.TIME;
var gameroom = req.params.id;
io.on('connect', function (socket) {
socket.emit('impulse', {
})
})
res.json({ success: true, message: 'received the time!'})
})
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname + '/public/app/views/index.html')); // Set index.html as layout
});
Replace this whole
io.on('connect', function (socket) {
socket.emit('impulse', {
})
}
with this
io.emit('impulse', {})

How to send message to frontend in case of MongoDb connection Failed

Is there any way to send error to frontend on mongoDb connection error.I had tried in a different different way but I didnt get a solution.
var express = require('express');
var session = require('express-session');
var MongoDBStore = require('connect-mongodb-session')(session);
var store = new MongoDBStore(
{
uri: config.connectionString,
collection: 'tbl_session'
});
// Catch errors
store.on('error', function(error) {
app.get('/',function(req,res){
res.send('NOT Connected....')
});
});
You can use web sockets to push this information to the UI.
const express = require('express');
const app = express();
const path = require('path');
const server = require('http').createServer(app);
const io = require('../..')(server);
const port = process.env.PORT || 3000;
var session = require('express-session');
var MongoDBStore = require('connect-mongodb-session')(session);
var store = new MongoDBStore(
{
uri: config.connectionString,
collection: 'tbl_session'
});
// Catch errors
store.on('error', function(error) {
socket.emit('mongodb-failed', error)
});
});
server.listen(port, () => {
console.log('Server listening at port %d', port);
});
// Routing
app.use(express.static(path.join(__dirname, 'public')));
io.on('connection', (socket) => {
// when socket emits 'mongodb-connection-failed', this listens and executes
socket.on('mongodb-failed', (data) => {
// we tell the client to execute 'new message'
socket.broadcast.emit('mongodb-connection-failed', {
errorDetails: data
});
});
});
now at client side:
var socket = io();
socket.on('mongodb-connection-failed', () => {
console.log('you have been disconnected');
//do more whatever you want to.
});
This above example is using socket.io.
You can use any web socket library, see more here

how to attach socket.io to SwaggerExpress

I am using swaggerexpress middleware and swagger.
I can't get to work with socket.io
What is the proper way to attach socket.io to my server created?
'use strict';
var SwaggerExpress = require('swagger-express-mw');
var app = require('express')();
var io = require('./api/helpers/socketio');
module.exports = app;
var config = {
appRoot: __dirname
};
SwaggerExpress.create(config, function(err, swaggerExpress) {
if (err) { throw err; }
swaggerExpress.register(app);
app.listen(10010, function () {
console.log('Application is start listening on localhost:10010');
});
io.on('connection',function(socket){
console.log("A user is connected: " + socket.id);
io.emit('message', "Welcome")
});
});
io.attach(app);
With that approach, my server is not getting up, got an error on socket.io attaching to app.
If you're okay using a different port for socket.io, you could do something like this:
var io = require('socket.io')(10011);
// Or maybe in your case:
// var io = require('./api/helpers/socketio')(10011);
io.on('connection', function(socket) {
console.log('user connected');
});
On the client you'd connect to it like this:
var socket = io('http://localhost:10011');
socket.on('connect', function() {
console.log('Socket connection established');
});

Good way of handling MongoError: server instance pool was destroyed

I'm running a daemon with a mongo connection pool. It runs fine for days but eventually it crashes and every subsequent request gets this error:
MongoError: server instance pool was destroyed
The code is similar to this:
var MongoClient = require('mongodb').MongoClient;
var express = require('express');
var app = express();
MongoClient.connect(config.mongo.url, function(err, db) {
app.use('/', function(req, res, next) {
db.collection('somecollection').find({}).toArray(function(err, result) {
console.log(result);
});
})
var server = require('http').Server(app);
server.listen(config.worker.port, function() {
var address = server.address();
logger.info({
address: address.address,
port: address.port
}, 'New Worker created');
});
});
Restarting the process fixes the issue, but I would like the application to somehow elegantly reconnect and reset the "db" object there.
This is what we are using - if connection fails, it tries to reconnect after 5 seconds. It is written for mongoose, but we are just re-running connection when detecting error, which should be done for any framework.
// Connect to mongodb
const connect = function () {
const options = {server: {socketOptions: {keepAlive: 1}}};
mongoose.connect(config.db, options);
};
connect();
mongoose.connection.on('error', err => {
let stack;
if (err) {
stack = err.stack;
}
winston.error('Mongo crashed with error', {err, stack});
}); // eslint-disable-line no-console
mongoose.connection.on('disconnected', () => {
setTimeout(connect, 5000);
});

Can't seem to get socket io to display any emits

I've been trying to figure out why I can't get any emits to show up in my terminal and it seems that everything is running fine.... except for seeing the emits. Here is my code
var express = require('express');
var path = require('path');
// Create a new Express application
var app = express();
var views = path.join(process.cwd(), 'views');
app.use("/static", express.static("public"));
// Create an http server with Node's HTTP module.
// Pass it the Express application, and listen on port 3000.
var server = require('http').createServer(app).listen(3000, function() {
console.log('listening on port ' + 3000)
});
// Instantiate Socket.IO hand have it listen on the Express/HTTP server
var io = require('socket.io')(server);
var game = require('./game');
app.get('/', function(req,res) {
res.sendFile(path.join(views, 'index.html'));
});
io.on('connect', function(socket) {
io.emit('connection', { message: "You are connected!" });
game.initGame(io, socket);
socket.emit('connected', { message: "You are connected!" });
io.sockets.emit('test', 'test')
});
Any help would be great!
Emits are not automatically printed. socket.emit will send a message back to the client, not to the terminal. Use console.log("whatever") to print to the terminal:
io.on('connect', function(socket) {
console.log('Client connected');
socket.on('test', function(data) {
console.log("Got message of type 'test'containing data:", data);
});
});

Resources