Cannot call method "on" of undefined (express and socket.io) - node.js

I want to export the socket.io object from my app.js of express
My app.js file is here: http://pastebin.com/Kfny4yVK
My bin/www file is here: http://pastebin.com/qGhPm6KE
In my app.js I do:
var app = express();
var http = require("http").Server(app);
var io = require("socket.io")(http);
exports.io = io;
In a routes file I do:
var io = require(__dirname+'/../app.js').io;
However, when I call the:
io.on
I get an undefined object error. Any idea why this is happening? It looks like nodejs is somehow modifying the io object at export? Is this possible? Is there a way to make this work?

With Express v4.x I use the following to export the socket.io object.
APP.JS
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
//Export sio module so socket.io can be used in other modules
module.exports.sio = io; //ADDED this
OTHER_FILE.JS
//Import sio module from app.js
var io = require('../app.js').sio;

Related

How do I serve files from a lower directory with Express 3.x?

This answer made it clear how to serve files from a lower directory than the program's root, like so:
var path = require('path');
var express = require('express');
var app = express();
app.use(express.static(path.join(__dirname, '../public')));
This worked fine. Now I'm trying to set up a socket.io server like so:
const express = require('express');
const server = express();
const io = require('socket.io')(server);
and socket.io is throwing the error:
Error: You are trying to attach socket.io to an express request
handler function. Please pass a http.Server instance.
Which makes sense, because now on the socket.io documentation, it's asks for a setup like this:
const app = require('express')();
const server = require('http').createServer(app);
const io = require('socket.io')(server);
io.on('connection', () => { /* … */ });
server.listen(3000);
But I don't know how to reconcile the old way of loading files from a lower directory like shown in the answer above with this new way of setting up express and socket.io, because where const app = require('express')(); as in the socket.io documentation, the error gets thrown TypeError: app.static is not a function.
How do I reconcile the now-outdated express path routing with the new express setup?
This is the way i did it in the old days of express 3.x.
var path = require('path');
var http = require('http');
var express = require('express');
var app = express();
app.use(express.static(path.join(__dirname, '../public')));
/* ... more routing logic, i.e app.get(...)*/
var server = http.createServer(app);
var io = require('socket.io')(server);
io.on('connection', () => {/* ... */});
server.listen(3000);
Hope it helps

I'm trying to run Node.js chat application what I have downloaded from git hub. So I'm getting error like "object is not a function"

This is my app.js code
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io') (server);// Encountered problem in this line "(server)object is not a function"
var port = process.env.PORT || 3000;
I also run this chat application and its working fine.
The problem is in this line :
var io = require('socket.io') (server);
Try this:
var io = require('socket.io').listen(server);
you forget to write .listen(server)

How to access io instance in a third part file?

I need to access my socket.io instance in some differents files, how do you make it works?
Here is what i tried:
main.js
var app = express();
var sockets = require('./sockets');
sockets.listen(app)
sockets.js
var io = require('socket.io');
exports.listen = function(app) {
io = io.listen(app);
//...
}
exports.io = io;
SomeClass.js
var io = require('./sockets').io;
var SomeClass = function() {
var Clients = io.sockets.clients('room');
//io is undefined...
}
exports.SomeClass = SomeClass;
In your file, io.sockets is undefined because you are starting your server incorrectly. Socket.IO expects a HTTP server instance, and you are instead passing an Express instance. You are also trying to change a variable after it has been exported, and that does not work. This is what you should be doing:
var http = require('http');
var express = require('express');
var app = express();
var server = http.createServer(app);
var io = require('socket.io').listen(server):
server.listen(80);
If you still wanted to split this up into files, you would have to put your Socket.IO instance in your main application, and pass it to other modules when requiring them.

Can't emit by socket.io?

I recently updated socket.io to latest version which is 0.9.8
Last time I worked with the app, I did something like this:
io.sockets.emit("logged",this);
And it worked. Now I get:
TypeError: Cannot call method 'emit' of undefined
at new Agent (/var/www/panel/models/agent.js:29:16)
at module.exports (/var/www/panel/modules/app.js:35:47)
at Query.Client.query (/var/www/panel/node_modules/mysql/lib/client.js:108:11)
at Query.EventEmitter.emit (events.js:85:17)
at Query._handlePacket (/var/www/panel/node_modules/mysql/lib/query.js:51:14)
at Client._handlePacket (/var/www/panel/node_modules/mysql/lib/client.js:319:14)
at Parser.EventEmitter.emit (events.js:88:17)
at Parser.write.emitPacket (/var/www/panel/node_modules/mysql/lib/parser.js:71:14)
at Parser.write (/var/www/panel/node_modules/mysql/lib/parser.js:576:7)
at Socket.EventEmitter.emit (events.js:88:17)
I thought it was because something about scope or whatever so I just did this:
// server.js
var express = require('express'),
server = express(),
Routes = require('./routes'),
App = require('./modules/app.js'),
database = require('./libraries/mysql.js'),
io = require('socket.io'),
mysql = require('mysql');
server.listen(8080);
io.listen(server);
io.sockets.emit('Hi there', {});
And it just doesn't work, same error, different line.
What am I doing wrong?
You need to save the return value of socketio.listen and interact with that. I recommend you follow the examples at socket.io. Something like this should do the trick:
var express = require('express'),
server = express(),
socketio = require('socket.io');
server.listen(8080);
var io = socketio.listen(server);
io.sockets.emit('Hi there', {});
Or even:
var express = require('express'),
server = express(),
io = require('socket.io').listen(server);
server.listen(8080);
io.sockets.emit('Hi there', {});

Connect2 and Socket.io

I'm trying to get connect and socket.io to work together nicely and simply. I have the following code on server side:
var connect = require('connect'),
io = require('socket.io');
var app = connect().use(connect.logger('dev'));
var sio = io.listen(app);
app.listen(8000);
when i open http://localhost:8000/socket.io/socket.io.js i'm get error:
Cannot GET /socket.io/socket.io.js
And Socket.IO not work, i'm trying copy file and load from another location, but socket.io requests do not reach the server
SOLUTION
if anyone comes to this issue, you need to wrap the connect/express app in a node http.Server. The app.listen() method is a convenience method for this and returns the server:
var io = require('socket.io');
var app = connect();
var server = app.listen(3000);
io.listen(server);
or the following is equivalent:
var io = require('socket.io');
var http = require('http');
var app = connect();
var server = http.createServer(app);
server.listen(3000);
io.listen(server);

Resources