Ich bin ziemlich neu in node.js und habe festgestellt, dass es ziemlich kompliziert ist, ein Projekt in mehrere Dateien zu unterteilen, wenn das Projekt größer wird. Ich hatte eine große Datei, die sowohl als Dateiserver als auch als Socket.IO-Server für ein Multiplayer-HTML5-Spiel diente. Ich möchte im Idealfall den Dateiserver, die Socket.IO-Logik (Lesen von Informationen aus dem Netzwerk und Schreiben in einen Puffer mit einem Zeitstempel, dann an alle anderen Spieler senden) und die Spielelogik trennen.
Anhand des ersten Beispiels aus socket.io, um mein Problem zu demonstrieren, gibt es normalerweise zwei Dateien. app.js
ist der Server und index.html
wird an den Client gesendet.
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>
Um die Logik von Dateiserver und Spielserver zu trennen, müsste die in einer Datei definierte Funktion "Handler" verwendet werden. Die anonyme Funktion würde einen Rückruf für io.sockets.on () verwenden, um in einer anderen Datei zu sein, und ich würde noch eine benötigen dritte Datei, um diese beiden Dateien erfolgreich einzuschließen. Im Moment habe ich Folgendes versucht:
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;
}
}
Spieleserver:
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);
}
}
Dies scheint zu funktionieren (der statische Inhalt wird ordnungsgemäß bereitgestellt und die Konsole zeigt deutlich einen Handshake mit Socket.IO an, wenn der Client eine Verbindung herstellt), obwohl niemals Daten gesendet werden. Es ist, als würden socket.emit () und socket.on () niemals aufgerufen. Ich habe sogar handler () geändert, gameserver.js
um hinzuzufügen, console.log('User connected');
aber dies wird nie angezeigt.
Wie kann ich Socket.IO in einer Datei und einen Dateiserver in einer anderen Datei haben und trotzdem erwarten, dass beide ordnungsgemäß funktionieren?
Antworten:
In socket.io 0.8 sollten Sie Ereignisse anhängen mit
io.sockets.on('...')
: Wenn Sie keine Namespaces verwenden, scheint Ihnen dersockets
Teil zu fehlen :io.listen(fileserver).sockets.on('connection', handler)
Es ist wahrscheinlich besser, eine Verkettung auf diese Weise zu vermeiden (möglicherweise möchten Sie das
io
Objekt später verwenden). So mache ich das gerade:// 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 }
Dann nach dem Erstellen des Servers
app
:// main.js var io = require('./lib/sockets').listen(app)
quelle
app.get('/some/url',function(req,res){ // I want to emit here })
Ich würde so etwas tun.
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);
und 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]); } }); }); } };
Ich habe nur einen Teil meines alten Codes kopiert und eingefügt - ich weiß nicht wirklich, was sich in den letzten Versionen von socket.io geändert hat, aber hier geht es mehr um die Struktur als um den tatsächlichen Code.
und ich würde nur 2 Dateien für Ihre Zwecke verwenden, nicht 3. Wenn Sie darüber nachdenken, es weiter aufzuteilen, vielleicht eine andere Datei für verschiedene Routen ...
hoffe das hilft.
quelle
var xxx = require('./xxx');
und Ihre App in mehrere Dateien aufteilen. Ich war gestern bei der Mongodb Conf und jemand von 10gen zeigte ein Spiel basierend auf Node / Mongo / Websockets ( github.com/christkv/mongoman ). Er sendet BSON-Daten über den Socket und decodiert die Daten auf dem Client - sorgt für eine schnellere Kommunikation zwischen Client / Server ... vielleicht ist es interessant für Sie!?Ich hatte auch einen Knaller und bin ziemlich zufrieden mit dem Ergebnis. Unter https://github.com/hackify/hackify-server finden Sie den Quellcode.
quelle
Ich habe eine andere Lösung. Sie können require.js verwenden, um ein Modul zu erstellen und "app" als Argument zu übergeben. Innerhalb des Moduls können Sie socket.io starten und Ihre Sockets organisieren.
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 });
In Ihrem socket.js- Modul können Sie Folgendes tun:
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; } });
Ich hoffe, ich helfe Ihnen mit meinem Beitrag.
quelle