13

I've been staring at node.js and socket.io examples all afternoon and i'm trying to piece together a simple page that will tell me how many users I have connected to the server.

I have read the documentation at http://socket.io/ as well as a few tutorials / questions here that outline exactly what i'm trying to do. I have also found create simple node js server and client which does not help me.

Version Information:

node.js - 0.6.15
express - 3.0.0alpha1
socket.io - 0.9.5 (socket.io-client is the same version, however does not find the resource... see comments)
ejs - 0.7.1

Here is my server code:

var express = require('express'),
    config = {
        port: 4000,
        hostname: 'localhost'
    };

var server = module.exports = express.createServer();
    /* server configuration */
    server.use(express.cookieParser('keyboard unicorn'));
    server.use(express.bodyParser());
    server.use(express.methodOverride());
    server.use(express.session({ secret: 'keyboard unicorn' }));
    server.engine('.html', require('ejs').__express);
    server.set('views', __dirname + '/lib/views');
    server.set('view options', { layout: false });
    server.set('view engine', 'html');
    server.use(server.router);
    server.use('/', express.static(__dirname + '/lib/assets'));

var io = require('socket.io').listen(server);

var connections = { 'length': 0 };

io.sockets.on('connection', function(socket) {
    socket.__fd = socket.fd;
    connections[socket.__fd]=socket.remoteAddress;
    ++connections.length;
    console.log('user connected! There are a total of ' + connections.length + ' users online.');
    return socket.on('disconnect',function(){
        delete conns[socket.__fd];
        --connections.length;
        console.log('user disconnected! There are a total of ' + connections.length + ' users remaining online.');
    });
});

server.get('/', function( req, res ) {
    res.render('index', {
        'page_title': 'sample application',
        'number_of_connections': connections.length
    });
});

server.listen(config.port, config.hostname);

Here is my client code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title><%= page_title %></title>
</head>
<body>
<div>There is a total of <%= number_of_connections %> user(s) connected.</div>
<script src="http://cdn.socket.io/stable/socket.io.js"></script>
<script type="text/javascript">
var socket = new io.Socket('localhost',{'port':4000});
socket.connect();
socket.on('connect', function() {
    console.log('connected');
});
</script>
</body>
</html>

Here is what is happening when I run the server, and connect with the client.

$ node server.js
   info  - socket.io started

then when I navigate to localhost:4000 on my web browser I get the page with '0' (number_of_connections). Also, I see nothing in the terminal for the server (the on.('connection' is never hit).

On the client, after a second or two, I start to get a massive number of errors (if I leave the console open for a few seconds it crashes the page) see image below:

enter image description here

Please, any help with where to start for debugging this would be appreciated! I just want to get this basic example up and running so I can start playing with / understanding nodejs and socket.io!

Community
  • 1
  • 1
rlemon
  • 17,518
  • 14
  • 92
  • 123
  • A good place to start would be your node version and socket.io version. I see that cdn.socket.io's version in 0.6. I see that I'm using socket.io 0.8.7 with node v0.6.4, for instance. Also, is there a reason you didn't just go with ``? You might give that a try and see if the result is different (as that would bypass the possibility of version errors) – Kato Apr 17 '12 at 20:35
  • `Failed to load resource: the server responded with a status of 404 (Not Found) http://localhost:4000/socket.io/socket.io.js` – rlemon Apr 17 '12 at 20:37
  • Hm, that's odd. Mine works out of the box, of course, so I can't be much help on why you can't use the local socket.io URL. Btw, my socket.io-client version is 0.8.7 (the same as socket.io's)--wonder if that matters... – Kato Apr 17 '12 at 20:45
  • my client is the same as my socket-io version – rlemon Apr 17 '12 at 20:59
  • Right, but the one you're using, cdn.socket.io/stable is at 0.6. I found a few comments stating issues with this older version. Wonder how to get your local to load? – Kato Apr 17 '12 at 21:05
  • hrmm. that is the question at hand. :P – rlemon Apr 17 '12 at 21:50
  • I had a similar problem. Hope this helps: http://stackoverflow.com/questions/7603224/node-server-socket-io-io-is-not-defined – Jack Apr 17 '12 at 23:00

4 Answers4

21

The problem is because of Express now being a function.

You need to do the following:

var express = require('express');
var app = express();
var server = app.listen(3000);

var io = require('socket.io').listen(server);
Renato Gama
  • 16,431
  • 12
  • 58
  • 92
Menztrual
  • 40,867
  • 12
  • 57
  • 70
  • @Linus G. Thiel pointed me to the correct answer, and I believe @tehlulz stumbled upon the correct answer but gave the wrong reason. I'll be referring to @tehlulz's code in this comment. It seems that in Express 3.0.x, the app itself, whether it's created with `express.createServer()` or `express()`, doesn't contain enough information to allow Socket.IO to listen to it directly. Rather, it's the return value of `app.listen(PORT)` that is what Socket.IO should be listening to, not `app` itself. – btown Jul 10 '12 at 19:42
  • I had exactly the same problem and this solution worked for me. +1 for the great answer – lhk Jul 26 '12 at 12:23
  • 1
    Too bad this isn't marked as the answer. This is how to get express 3.0 to work with socket.io – Benny Jan 10 '13 at 07:23
  • This needs more upvotes. This was the correct answer after much toiling! – Tilo Mitra Apr 16 '13 at 07:01
6

Express 3.0.0alpha and socket.io are not (directly) compatible, due to changes in Express between 2.* and 3.* (or rather, changes in Connect between 1.* and 2.*). I would recommend you to downgrade to Express 2.5.9 for the time being, or you can follow this advice from Express' author, TJ Holowaychuk.

Linus Thiel
  • 38,647
  • 9
  • 109
  • 104
4

I set up a test environment, installed express 3.0 and socket.io 0.9.5, and reproduced your error.

Then I ran npm install express@2.5.1 made a couple backwards tweaks based on the migration guide, and it ran great.

So I'm going to go ahead and suggest that socket.io is probably not compatible with express 3 yet, which still looks pretty unstable.

My app.js tweaked for express 2:

var express = require('express'),
    config = {
    port: 8080,
    hostname: 'localhost'
};

var server = module.exports = express.createServer();
/* server configuration */
server.set('views', __dirname + '/lib/views');
server.set('view options', { layout: false });
server.set('view engine', 'ejs');
//server.register('.html', 'ejs');require('ejs').__express);
server.use(express.cookieParser('keyboard unicorn'));
server.use(express.bodyParser());
server.use(express.methodOverride());
server.use(express.session({ secret: 'keyboard unicorn' }));
server.use('/', express.static(__dirname + '/lib/assets'));
server.use(server.router);

var io = require('socket.io').listen(server);

io.set('log level', 2);

var connections = { 'length': 0 };

server.get('/', function( req, res ) {
        res.render('index', {
                'page_title': 'sample application',
                    'number_of_connections': connections.length
                    });
    });

io.sockets.on('connection', function(socket) {
        socket.__fd = socket.fd;
        connections[socket.__fd]=socket.remoteAddress;
        ++connections.length;
        console.log('user connected! There are a total of ' + connections.length + ' users online.');
        return socket.on('disconnect',function(){
                delete conns[socket.__fd];
                --connections.length;
                console.log('user disconnected! There are a total of ' + connections.length + ' users remaining online.');
            });
    });

server.listen(config.port);

My index.ejs file:

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="utf-8">
   <title><%= page_title %></title>
</head>
<body>
<div>There is a total of <%= number_of_connections %> user(s) connected.</div>
<!--<script src="http://cdn.socket.io/stable/socket.io.js"></script>-->
<script src='/socket.io/socket.io.js'></script>
<script type="text/javascript">
   var socket = io.connect('http://hostname.com:8080');
   socket.on('connect', function() {
      console.log('connected');
   });
</script>
</body>
</html>

I hope something here helps.

Kato
  • 40,352
  • 6
  • 119
  • 149
  • wow, amazingly helpful reply. I wish I could upvote you twice! I will switch my installation and hope this corrects the issue for me as well! – rlemon Apr 17 '12 at 23:46
  • I have made the changed you have suggested and tweaked my app a bit to make it compatible with the older version... now i'm getting `warn - unknown transport: "undefined"\n info - unhandled socket.io url` – rlemon Apr 18 '12 at 12:56
  • Did you uncomment the .html/ejs bit? That caused me some headaches and I just converted the index.html to an index.ejs instead. I would start there, but this could be just about anything. Consider posting a new question with your new config; somebody will know :) – Kato Apr 18 '12 at 18:09
  • yea... this is happening when the heartbeat from the client is run. Also, the application still fails to tell me when users are connected... i.e. the 'connection' event is never picked up. – rlemon Apr 18 '12 at 18:18
0

replace app.use(express.bodyParser());, with

app.use(express.json());
app.use(express.urlencoded());

...save file, restart node server.

Greg
  • 18,111
  • 5
  • 46
  • 68