chollinger
chollinger

Reputation: 1117

node.js + socket.io + express.js: No connection

I've been trying to set up a simple socket.io example, but it refuses to work properly. The client runs on Apache2 and should access the node.js-server via the port 3000.

There doesn't seem to be any connection and it doesn't seem to matter whether the server's actually running - if the node.js-process is manually stopped on the server ($ kill xyz), my client-console throws no errors whatsoever. The exact same result occurs when the app is running (info - socket.io started).

Server:

// Check dependencies & setup backend
var express = require('express');
var server = express();
var http = require('http');
var app = http.createServer(server); // somehow needed? ("Socket.IO's `listen()` method expects an `http.Server` instance as its first parameter.")
var socket = require('socket.io');
// listen @ port 3000 as definied by proxy
server.listen(3000);
// listen w/ socket.io as well
var io = socket.listen(app);

...

// socket.io
// TODO: test, added 01/03/14 
io.set('match origin protocol', true);
io.set('log level', 2);
var clients = io.sockets.clients();
io.sockets.on('connection', function(client) {
    console.log('Connection from ' + client);

    client.emit('news', {
        hello : 'world'
    });

    client.on('event', function(data) {
        console.log(data);
    });
});

Client:

<script type="text/javascript" src="./js/socket.io.js" ></script>
        <script>
            try {
                var socket = io.connect('https://localhost:3000');
                console.log(io);
                console.log('check 1', socket.socket.connected); // false

                socket.on('connect', function() {
                    console.log('check 2', socket.socket.connected); // not reached
                });

                socket.on('news', function(data) {
                    console.log(data);
                });

            } catch(error) {
                console.log(error);
            } finally {
                console.log('fin');
            }
        </script>

Edit 2:

This code works, but only locally. I've even installed Apache 2.4 on the server to ensure I've access to WebSockets (I read somewhere they weren't available in 2.2.x). Server:

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

app.use(express.static(__dirname + '/'));

io.sockets.on('connection', function (socket) {
  socket.emit('news', { hello: 'world' });
  socket.on('my other event', function (data) {
    console.log(data);
  });
});

Client:

<script type="text/javascript" src="js/socket.io.js" ></script> 
        <script>
            var socket = io.connect('ws://localhost:3000');
            socket.on('news', function(data) {
                console.log(data);
                socket.emit('my other event', {
                    my : 'data'
                });
            });

        </script>

Upvotes: 2

Views: 17304

Answers (2)

chollinger
chollinger

Reputation: 1117

Alright guys, I finally have it up and running.

What I did was to migrate my reverse proxy from Apache to a node.js/node-http-proxy-solution. I'm not sure whether this is actually mandatory - but after re-configuring Apache 2.2.2 and even compiling Apache 2.4.7 didn't help, I figured it could be worth a shot. I also switched to a subdomain rather a subdir, as subdirs seems to cause problems in some cases as well. Again, dunno whether this was just a precaution or if this is actually necessary.

What I'm pretty sure is of relevance, however, is how to load the socket.io.js. Since my reverse proxy already forwards requests to the correct (internal) IP, I have to access both socket.io.js as well as the actual Websocket via the TLD w/o ports or ws://.

Long story short, here's the relevant code:

Server

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

app.use(express.static(__dirname + '/'));

console.log('Express server started on port %s', app);

io.sockets.on('connection', function (socket) {
  socket.emit('news', { hello: 'world' });
  socket.on('my other event', function (data) {
    console.log(data);
  });
});

Client

<script src="http://mysubdomain.mydomain.com/socket.io/socket.io.js"></script>
<script>
    var socket = io.connect('http://mysubdomain.mydomain.com');
    // , {secure: true}

    socket.on('news', function(data) {
        console.log(data);
    });
</script>

Proxy

var fs = require('fs'), httpProxy = require('http-proxy');

// This will crash as soon as Apache isn't running or the port isn't binded elsewhere
// TODO: fix
var proxyTable = {
    'mydomain.com/subdir' : '127.0.0.1:3000',
    'mysubdomain.mydomain.com' : '127.0.0.1:3000'
};

var httpOptions = {
    hostnameOnly : false,
    router : proxyTable
};

var httpsOptions = {
    hostnameOnly : false,
    router : proxyTable,
    https : {
        key : fs.readFileSync('/path/key', 'utf8'),
        cert : fs.readFileSync('/path/cert', 'utf8')
    }
};

httpProxy.createServer(httpOptions).listen(80); 
httpProxy.createServer(httpsOptions).listen(443);

Last but not least, for anyone stumbling upon this via google, versions used:

$ npm list --depth=0
myapp@0.0.0 /path/app
├── express@3.4.7
└── socket.io@0.9.16

$ npm list --depth=0
/path/proxy
└── http-proxy@0.10.4

Upvotes: 7

moka
moka

Reputation: 23053

Please follow examples here: http://socket.io/#how-to-use

var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app);
var socket = require('socket.io');
var io = socket.listen(server);
app.listen(3000);

Additionally this is wrong:

io.connect('https://localhost:3000');

It should be ws://localhost:3000/

Upvotes: 4

Related Questions