Reputation: 1117
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
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
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