Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Separating file server and socket.io logic in node.js

I'm fairly new to node.js and I've found its quite complicated separating a project into multiple files as the project grows in size. I had one large file before which served as both a file server and a Socket.IO server for a multiplayer HTML5 game. I ideally want to separate the file server, socket.IO logic (reading information from the network and writing it to a buffer with a timestamp, then emitting it to all other players), and game logic.

Using the first example from socket.io to demonstrate my problem, there are two files normally. app.js is the server and index.html is sent to the client.

app.js:

var app = require('http').createServer(handler)   , io = require('socket.io').listen(app)   , fs = require('fs')  app.listen(80);  function handler (req, res) {   fs.readFile(__dirname + '/index.html',   function (err, data) {     if (err) {       res.writeHead(500);       return res.end('Error loading index.html');     }      res.writeHead(200);     res.end(data);   }); }  io.sockets.on('connection', function (socket) {   socket.emit('news', { hello: 'world' });   socket.on('my other event', function (data) {     console.log(data);   }); }); 

index.html:

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

To separate file server and game server logic I would need the function "handler" defined in one file, I would need the anonymous function used a callback for io.sockets.on() to be in another file, and I would need yet a third file to successfully include both of these files. For now I have tried the following:

start.js:

var fileserver = require('./fileserver.js').start()   , gameserver = require('./gameserver.js').start(fileserver); 

fileserver.js:

var app = require('http').createServer(handler),     fs = require('fs');  function handler (req, res) {   fs.readFile(__dirname + '/index.html',   function (err, data) {     if (err) {       res.writeHead(500);       return res.end('Error loading index.html');     }      res.writeHead(200);     res.end(data);   }); }  module.exports = {     start: function() {         app.listen(80);         return app;     } } 

gameserver:

var io = require('socket.io');  function handler(socket) {     socket.emit('news', { hello: 'world' });     socket.on('my other event', function (data) {         console.log(data);     }); }  module.exports = {      start: function(fileserver) {                io.listen(fileserver).on('connection', handler);     }  } 

This seems to work (the static content is properly served and the console clearly shows a handshake with Socket.IO when the client connects) although no data is ever sent. It's as though socket.emit() and socket.on() are never actually called. I even modified handler() in gameserver.js to add console.log('User connected'); however this is never displayed.

How can I have Socket.IO in one file, a file server in another, and still expect both to operate correctly?

like image 321
stevendesu Avatar asked Mar 14 '12 20:03

stevendesu


People also ask

Does Socket.IO need a server?

Socket.io, and WebSockets in general, require an http server for the initial upgrade handshake. So even if you don't supply Socket.io with an http server it will create one for you.

Which is better Socket.IO or WS?

Both WebSocket vs Socket.io are popular choices in the market; let us discuss some of the major Difference Between WebSocket vs Socket.io: It provides the Connection over TCP, while Socket.io is a library to abstract the WebSocket connections. WebSocket doesn't have fallback options, while Socket.io supports fallback.

How many Socket.IO connections can a server handle?

Once you reboot your machine, you will now be able to happily go to 55k concurrent connections (per incoming IP).


1 Answers

In socket.io 0.8, you should attach events using io.sockets.on('...'), unless you're using namespaces, you seem to be missing the sockets part:

io.listen(fileserver).sockets.on('connection', handler) 

It's probably better to avoid chaining it that way (you might want to use the io object later). The way I'm doing this right now:

// sockets.js var socketio = require('socket.io')  module.exports.listen = function(app){     io = socketio.listen(app)      users = io.of('/users')     users.on('connection', function(socket){         socket.on ...     })      return io } 

Then after creating the server app:

// main.js var io = require('./lib/sockets').listen(app) 
like image 54
Ricardo Tomasi Avatar answered Sep 20 '22 15:09

Ricardo Tomasi