node.js socket.io

Separar servidor de archivos y lógica socket.io en node.js



(4)

En socket.io 0.8, debe adjuntar eventos utilizando io.sockets.on(''...'') , a menos que esté usando espacios de nombres, parece que le falta la parte de los sockets :

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

Probablemente sea mejor evitar encadenarlo de esa manera (es posible que desee utilizar el objeto io más adelante). La forma en que estoy haciendo esto ahora mismo:

// 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 }

Luego, después de crear la app servidor:

// main.js var io = require(''./lib/sockets'').listen(app)

Soy bastante nuevo en node.js y me resulta bastante complicado separar un proyecto en varios archivos a medida que el proyecto crece en tamaño. Tenía un archivo grande antes del cual funcionaba como servidor de archivos y como servidor Socket.IO para un juego HTML5 multijugador. Lo ideal es separar el servidor de archivos, la lógica de socket.IO (leer la información de la red y escribirla en un búfer con una marca de tiempo y luego emitirla a todos los demás jugadores) y la lógica del juego.

Usando el primer ejemplo de socket.io para demostrar mi problema, normalmente hay dos archivos. app.js es el servidor y index.html se envía al cliente.

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>

Para separar el servidor de archivos y la lógica del servidor de juegos necesitaría la función "manejador" definida en un archivo, necesitaría que la función anónima utilizara una devolución de llamada para io.sockets.on () para estar en otro archivo, y necesitaría una tercer archivo para incluir exitosamente estos dos archivos. Por ahora, he intentado lo siguiente:

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; } }

Servidor de juegos:

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); } }

Esto parece funcionar (el contenido estático se sirve correctamente y la consola muestra claramente un apretón de manos con Socket.IO cuando el cliente se conecta), aunque nunca se envían datos. Es como si nunca se llamaran realmente socket.emit () y socket.on (). Incluso modifiqué el controlador () en gameserver.js para agregar console.log(''User connected''); sin embargo, esto nunca se muestra.

¿Cómo puedo tener Socket.IO en un archivo, un servidor de archivos en otro y aún esperar que ambos funcionen correctamente?


Haría algo así.

app.js

var app = require(''http'').createServer(handler), sockets = require(''./sockets''), 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); }); } sockets.startSocketServer(app); app.listen(80);

y sockets.js

var socketio = require(''socket.io''), io, clients = {}; module.exports = { startSocketServer: function (app) { io = socketio.listen(app); // configure io.configure(''development'', function () { //io.set(''transports'', [''websocket'', ''xhr-polling'']); //io.enable(''log''); }); io.configure(''production'', function () { io.enable(''browser client minification''); // send minified client io.enable(''browser client etag''); // apply etag caching logic based on version number io.set(''log level'', 1); // reduce logging io.set(''transports'', [ // enable all transports (optional if you want flashsocket) ''websocket'' , ''flashsocket'' , ''htmlfile'' , ''xhr-polling'' , ''jsonp-polling'' ]); }); // io.sockets.on(''connection'', function (socket) { console.log("new connection: " + socket.id); socket.on(''disconnect'', function () { console.log("device disconnected"); }); socket.on(''connect_device'', function (data, fn) { console.log("data from connected device: " + data); for (var col in data) { console.log(col + " => " + data[col]); } }); }); } };

simplemente copié y pegué parte de mi código anterior, no sé realmente qué cambió en las últimas versiones de socket.io, pero esto se trata más de la estructura que del código real.

y solo usaría 2 archivos para sus propósitos, no 3. cuando piense en dividirlo aún más, tal vez otro archivo para diferentes rutas ...

espero que esto ayude.



Tengo otra solución. Puede usar require.js creando un módulo y pasar "aplicación" como argumento. Dentro del módulo puede iniciar socket.io y organizar sus sockets.

app.js :

var requirejs = require(''requirejs''); requirejs.config({ baseUrl: ''./'', nodeRequire: require }); requirejs([''sockets''], function(sockets) { var app = require(''http'').createServer() , fs = require(''fs'') , io = sockets(app); // do something // add more sockets here using "io" resource });

En su módulo socket.js puede hacer algo como esto:

define([''socket.io''], function(socket){ return function(app){ var server = app.listen(3000) , io = socket.listen(server); io.sockets.on(''connection'', function (socket) { console.log(''connected to socket''); socket.emit(''news'', { hello: ''world'' }); socket.on(''my other event'', function (data) { console.log(data); }); // more more more }); return io; } });

Espero ayudarte con mi contribución.