Express-Generator - Including socket.io (bin/www) - node.js

I've always been a bit of a Perl/PHP sorta guy, but I fancy a change and Node JS seems like the right place for me to go next.
I've watched a good few hours of tutorials on YouTube and read some posts on here - but I have come up a bit stuck.
I'd like to include socket.io in my express-generated application (v4.10.6).
At the same time though, I don't really want to include the socket.on(...) statements in one file - i'd much rather split it out like you would with a route.
Given that the express-generated app is started in bin/www, i'm confused as to where I need to require('socket.io') and point all the 'on' events to.
This post on stackoverflow, I think may answer my question - but it suggests all the socket handlers are in the ./sockets/base.js file - and I am confused by the Gofilord's response to the answer.
Please forgive my ignorance here - this is all a bit alien to me at the moment, and thank you, as always for taking the time to read this and your help.
/bin/www
#!/usr/bin/env node
var debug = require('debug')('rhubarb');
var app = require('../app');
app.set('port', process.env.PORT || 1127);
var server = app.listen(app.get('port'), function() {
debug('Express server listening on port ' + server.address().port);
});

Its typical to require socket.io in app.js and then to tell your io sever to listen to your application. Using the example you posted, that would look like this:
var debug = require('debug')('rhubarb');
var app = require('../app');
var server = require('http').Server(app);
var io = require('socket.io')(server);
app.set('port', process.env.PORT || 1127);
var server = server.listen(app.get('port'), function() {
debug('Express server listening on port ' + server.address().port);
});
The socketio docs do a really good job of explaining this. Here's an example from their homepage:
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(80);
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
io.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
Update:
I typically modularize socketio setup by creating a lib called io.js in /lib with something like this:
module.exports = function(server){
var io = require('socket.io')(server);
// catch errors
io.on('error', function(err){
throw err;
})
// Set Socket.io listeners by creating a socket.io middleware
// attachEventlisteners would live in `/controllers`
io.use(attachEventlisteners);
io.on('connection', function (socket) {
// do things
});
return io; // so it can be used in app.js ( if need be )
}
then in app.js i can simply pass the server in when I require it:
var io = require('./lib/io')(server);
You dont need to do any thing further in app.js since everything is setup in /lib/io.js, but if you wanted to you could because the io server is returned.

Related

I have a two node js servers. second server is for the socket connection. How do I establish a connection between these two servers?

I'm setting up another nodejs server for the socketio, which is index.js. so I have two servers one is app.js and other one is index.js. so how do i establish a connection between these two servers?
If I correctly get what you wanted to do. You wanted to separate the file of the recieving of socket. Here's my code below.
on your app.js
var app = Express();
var server = require('http').createServer(app);
var io = SocketIo.listen(server);
server.listen(function(){
require('/path/of/your/index.js')(io);
})
and on your index.js
module.exports = function(io){
io.on('connection', function(socket){
*your codes here*
});
}
Can you please explain your problem in detail.And second thing, I don't understand why you want to establish two servers.Because you can always connect socket.io using your Node server.The code for it is below:
//Server side code
var app = require('http').createServer(handler)
var io = require('socket.io')(app);
var fs = require('fs');
app.listen(80);
io.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
//Client Side code
var socket = io.connect();
socket.emit('my other event', {
data : 'Hello'
});
This is very basic example for client-server communication using socket.io
I hope you will get your answer.

Socket.io with Express, emit not working within express route

Either I have a fundamental misunderstanding of how socket.io works (highly likely), or I am just finding some bug that nobody knows about (nearly impossible).
I've been trying to integrate express with socket.io. On the client side, everything works fine: user clicks button, event emits, everybody's happy.
However, let's say I want to emit this event from within an express route before rendering a page. The event never seems to be emitted. From all the questions on this that I've looked at, I'm supposed to be able to simply plug my "io" instance into my app and then access it from within my routes.
So this is my setup...
// index.js
var app = express();
var port = process.env.PORT || 3700
var io = require('socket.io').listen(app.listen(port));
io.on('connection', function (socket) {
console.log("Socket connected on port " + port)
socket.on('send', function (data) {
console.log("WAFFLES")
});
});
console.log('The magic happens on port ' + port);
require('./app/routes.js')(app, io);
// app/routes.js
module.exports = function(app, io){
app.get('/', function(req, res){
io.on('connection', function (socket) {
console.log("Hello from the route!")
socket.emit('send', {message: 'urdum'})
});
res.render('index')
})
}
So in this instance, I want to be able to go into the / route, see "Hello from the route" and then "WAFFLES" logged to the console after emitting the "send" event. Instead I get absolutely nothing.
I've tried to pass in "io" via app.set('socketio', io). But no matter what, nothing works.
I've also tried emitting the event within the route without the io.on('connection') and simply just doing
io.emit('send' ...)
OR
io.sockets.emit('send' ...)
I have a fundamental misunderstanding of how socket.io works (highly likely)
You are right,
This is typical setup for socket-io, read more in https://socket.io/docs/
// index.js
var express = require('express');
var socketio = require('socket.io');
var http = http = require('http');
var app = express();
// Attach Socket.io
var server = http.createServer(app);
var io = socketio.listen(server);
app.set('socketio', io); // <-- bind socket to app
app.set('server', server); // <-- optional
io.on('connection', function (socket) {
console.log("Socket connected on port " + port);
});
app.listen(3000);
server.listen(3001) // <-- socket port
// app.get('server').listen(3001); // <-- use server or app.get('server')
In your router, access socket by req.app.get('socketio');
// app/routes.js
module.exports = function(app, io){
app.get('/', function(req, res){
var socketio = req.app.get('socketio');
socketio.emit('send', {message: 'urdum'});
res.render('index')
})
}

nodejs socket.io express handshake error

I try to create a real time app by socket.io.
Server side:
var express = require('express');
var io = require('socket.io');
var engine = require('ejs-locals');
var app = express()
, server = require('http').createServer(app)
, io = io.listen(server);
app.engine('ejs', engine);
app.set('view engine', 'ejs');
app.get('/', function(req, res){
res.redirect('/login')
});
app.use(express.static(__dirname + '/public'));
app.listen(3001);
io.sockets.on('connection', function (socket) {
console.log('Client connected...');
socket.on('send_login_data', function (data) {
console.log(data);
});
});
Client side:
var socket = io.connect('http://localhost:3001');
socket.on('connect_failed', function(){
console.log('Connection Failed');
});
socket.on('connecting', function () {
console.log('connecting...');
});
socket.on('connect', function () {
console.log('connected!');
});
I caught the next error:
GET http://localhost:3001/socket.io/1/?t=1447539302809 404 (Not Found)
As I understand, it's a handshake error.
How can I fix it?
Thanx.
First off, make absolutely sure there are no errors showing anywhere in case some module isn't installed properly.
Then, make sure you have the same version number of socket.io on client and server and that you have the server-side version installed on the server.
Then, I've seen folks have issue with this before, even when following the instructions on the socket.io web site and it's never been clear exactly what was wrong with that sequence. But, what I know is that this sequence will work:
var express = require('express');
var app = express();
var server = app.listen(3001);
var io = require('socket.io').listen(server);
See related issues: Where is my client side socket.io? and Node + Socket.io Connection issue
I don't know if this is causing the issue or not, but you are attempting to redefine the io variable when it has already been declared in this:
var io = require('socket.io');
var app = express()
, server = require('http').createServer(app)
, io = io.listen(server);
The second reference to io = io.listen(server) is essentially this:
var io = require('socket.io');
var app = express();
var server = require('http').createServer(app);
var io = io.listen(server);
Which is not correct Javascript. Again, may not be causing your issue, but it is not technically proper Javascript.

socket.io not working node.js

I am not able to run socket.io code in node.js, console.log() is also not displaying when running the code. Below is the code.
app.js
var express = require('express');
var http = require('http');
var app = express();
app.set('port', process.env.PORT || 3000);
app.post('/testStream',test.testStream);
var server = http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
module.exports.appServer = server;
and I have created a test.js file where I am accessing this exported variable appServer.
var server = require('../app.js');
exports.testStream = function(req,res){
var io = require('socket.io').listen(server.appServer);
io.on('connection',function(socket){
console.log("in socket");
fs.readFile('E:/temp/testimg.png',function(err,buf){
socket.emit('image',{image: true,buffer: buf});
console.log("test image");
});
})
}
when the code runs it stucks and not showing the console.logs(). What I am doing wrong over here. Any help is very much appreciated.
I would suggest following the code structure as suggested in socket.io docs.
Also, you should not be calling io.listen or io.on('connection') inside your testStream express middleware. These are things you should only be doing once, and ideally they should happen during startup, inside app.js and not in reaction to a POST request. In fact, I'm not sure what the purpose of your testStream middleware is, its not even returning any response (eg res.end())
If you want to handle socket connections in a separate module you can, but instead of exporting your app's server the way you are, try passing the io instance as variable to your submodule. In short, try this:
app.js
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var test = require('./test')(io);
app.set('port', process.env.PORT || 3000);
server.listen(app.get('port'), function() {
console.log('Express server listening on port ' + app.get('port'));
});
test.js
module.exports = function(io) {
io.on('connection', function(socket) {
console.log("in socket");
fs.readFile('E:/temp/testimg.png', function(err, buf) {
socket.emit('image', {
image: true,
buffer: buf
});
console.log("test image");
});
});
};

Socket.io 1.0.6 client event

I am currently learning to use socket.io with node js but I'm having a hard time because I think something may have changed between versions. I have a litte demo using 1.0.4 in which I use something like this to send events from the client and receive them in the server:
SERVER
var socketio = require('socket.io');
var http = require('http');
var app = express();
var server = http.Server(app);
var io = socketio.listen(server);
var port = process.env.PORT || 8080;
server.listen(port, function(){
console.log("Express server listening on port " + port);
});
io.on('connection', function (socket) {
socket.emit('connected');
socket.on('myEvent', function(){
console.log('myEvent has been emitted');
});
});
CLIENT
$(document).ready(function(){
$('#button').click(function(){
emitEvent();
});
});
var socket = io.connect('http://localhost:8080/');
socket.on('connected', function () {
alert('server says I am connected');
});
function emitEvent(){
socket.emit('myEvent');
}
With both versions I can open the socket on the client and receive the 'connected' event sent later from the server than launches the alert function. The problem here is when I want to send any other event from the client. "socket.emit('myEvent');" in the emitEvent function seems to work fine for the 1.0.4 version but not for the 1.0.6 version. I have been looking for info about the changes and trying to understand the whole module but cannot get to the solution. Does anyone know what am I doing wrong? Obviously the way sending client events has changed. I would appreciate if someone could help me with this issue. Thanks in advance.
I didn't understand the problem actually. But here's the code for your functionality.
client:
var socket = io.connect();
$('#button').click(function(){
socket.emit('myEvent');
});
socket.on('connected', function(){
alert "you are connected";
});
server:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(app);
var port = process.env.PORT || 8080;
app.listen(port);
io.on('connection', function(socket){
socket.on('myEvent', function(){
socket.emit('connected');
console.log('emmited succesfully');
});
});

Resources