在node.js中分离文件服务器和socket.io逻辑

我对node.js相当陌生,随着项目规模的扩大,我发现将项目分割成多个文件相当复杂。 我之前有一个大文件作为多人游戏HTML5游戏的文件服务器和Socket.IO服务器。 理想情况下,我想分离文件服务器,socket.IO逻辑(从networking读取信息并将其写入具有时间戳的缓冲区,然后发送给所有其他玩家)以及游戏逻辑。

使用socket.io中的第一个例子来演示我的问题,通常有两个文件。 app.js是服务器, index.html发送给客户端。

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> 

要分离文件服务器和游戏服务器逻辑,我需要在一个文件中定义的函数“处理程序”,我需要匿名函数使用io.sockets.on()的callback在另一个文件中,我还需要一个第三个文件成功包含这两个文件。 现在我已经尝试了以下几点:

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

游戏服务器:

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

这似乎工作(静态内容是正确的服务和控制台清楚地显示与客户端连接时握手与Socket.IO)虽然没有数据发送。 就好像socket.emit()和socket.on()从来没有被实际调用过。 我甚至在gameserver.js修改了handler()来添加console.log('User connected'); 然而这从来没有显示。

如何在一个文件中使用Socket.IO,在另一个文件服务器中使用Socket.IO,并且仍然希望两者都能正常运行?

在socket.io 0.8中,你应该使用io.sockets.on('...')来附加事件,除非你使用了命名空间,你似乎缺less了sockets部分:

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

避免以这种方式链接可能会更好(以后可能需要使用io对象)。 我现在这样做的方式:

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

然后创build服务器app

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

我会做这样的事情。

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

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

我只是复制并粘贴了一些旧的代码 – 不知道在最新版本的socket.io中改变了什么,但是这比实际的代码更多地关于结构。

我只会使用2个文件为你的目的,而不是3.当你想分裂进一步,也许一个其他文件的不同路线…

希望这可以帮助。

我对此也有了一些认识,我对结果相当满意。 查看https://github.com/hackify/hackify-server获取源代码。;

我有另一个解决scheme。 您可以使用require.js创build一个模块,并将“app”作为参数。 在模块内,你可以启动socket.io并组织你的套接字。

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

在你的socket.js模块中,你可以这样做:

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

我希望能帮助你。