2012-03-14 19 views
60

में socket.io तर्क मैं काफी Node.js के लिए नया हूँ और मैं एकाधिक फ़ाइलों में एक परियोजना को अलग परियोजना के रूप में आकार में बढ़ता है इसकी काफी जटिल पाया है। मेरे पास एक बड़ी फ़ाइल थी जो पहले एक मल्टीप्लेयर एचटीएमएल 5 गेम के लिए फाइल सर्वर और सॉकेट.आईओ सर्वर दोनों के रूप में काम करती थी। मैं आदर्श रूप फ़ाइल सर्वर, socket.IO तर्क (नेटवर्क से जानकारी पढ़ रहे हैं और एक बफर करने के लिए इसे लिखने के एक टाइमस्टैम्प के साथ है, तो अन्य सभी खिलाड़ियों के लिए यह उत्सर्जन), और खेल तर्क अलग करना चाहते हैं।अलग फ़ाइल सर्वर और Node.js

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() के लिए कॉलबैक का उपयोग किया, और इन फ़ाइलों में सफलतापूर्वक शामिल करने के लिए मुझे अभी तक एक तीसरी फ़ाइल की आवश्यकता होगी।

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

} 

यह लगता है काम करने के लिए (स्थिर अभी के लिए मैं निम्नलिखित की कोशिश की है सामग्री ठीक से परोसा जाता है और जब ग्राहक क्लाइंट कनेक्ट करता है तो कंसोल स्पष्ट रूप से सॉकेट.आईओ के साथ हैंडशेक दिखाता है) हालांकि कोई डेटा नहीं है कभी भेजा ऐसा लगता है कि socket.emit() और socket.on() को वास्तव में कभी नहीं कहा जाता है। मैं भी console.log('User connected'); लेकिन इस प्रदर्शित नहीं है जोड़ने के लिए हैंडलर संशोधित() gameserver.js में।

मेरे पास एक फ़ाइल में सॉकेट.आईओ कैसे हो सकता है, एक फ़ाइल सर्वर दूसरे में, और फिर भी दोनों सही ढंग से काम करने की अपेक्षा करते हैं?

+4

क्या आप एक्सप्रेस जेएस ढांचे को जानते हैं? http://expressjs.com/ यह बहुत अच्छा है और वास्तव में आपको अपने आवेदन की संरचना में मदद करता है। github (https://github.com/visionmedia/express/tree/master/examples) पर उदाहरणों का एक टन है शायद कुछ ऐसा है जो आपकी समस्या से आपकी मदद कर सकता है ... – pkyeck

+1

@pkyeck: मैं पढ़ रहा हूं अभिव्यक्ति करने के लिए अब यह पता लगाने और समझने के लिए कि यह मुझे कैसे लाभ पहुंचा सकता है, लेकिन अब तक मुझे जो चाहिए वह उससे अधिक जटिल लगता है। मैं वास्तव में चाहता हूं कि मेरे तर्क को गेम सर्वर और फ़ाइल सर्वर के लिए दो अलग-अलग फाइलों में अलग करना है, फिर एक तीसरी फ़ाइल है जो दोनों सर्वरों को ठीक से शुरू करती है। – stevendesu

+0

क्या आपके पास मेरा "नया" उत्तर देखने का समय था? – pkyeck

उत्तर

74

सॉकेट.io 0 में।8, आप, io.sockets.on('...') का उपयोग कर की घटनाओं जब तक आप नामस्थान का उपयोग कर रहे देते हैं चाहिए, तो आप 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 
} 

फिर सर्वर app बनाने के बाद:

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

ग्रेट उत्तर, krakenJS को पोर्ट करने का प्रयास कर रहा है लेकिन socket.io मॉड्यूल कभी शुरू नहीं होता है:/ – Ms01

+1

हम 'वापसी io' का उपयोग नहीं कर रहे हैं? यह सिर्फ var io के लिए है। – Sobiaholic

+0

अगर मैं एक उत्सर्जन अनुरोध ट्रिगर करना चाहता हूं? पूर्व के लिए, 'app.get ('/some/url ', फ़ंक्शन (req, res) {// मैं यहां उत्सर्जित करना चाहता हूं}) ' –

5

मैं कुछ इस तरह करना होगा।

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


         }); 
       }); 
     } 
}; 

मैं सिर्फ नकल & मेरे पुराने कोड के कुछ चिपकाया - वास्तव में नहीं पता है कि सॉकेट के अंतिम संस्करण में बदल दिया है। io, लेकिन यह वास्तविक कोड की तुलना में संरचना के बारे में अधिक है।

और मैं केवल 2 फ़ाइलें अपने उद्देश्यों, नहीं 3. के लिए जब आप इसे अलग-अलग मार्गों के लिए एक अन्य फ़ाइल ...

आशा है कि यह मदद करता है बंटवारे आगे, हो सकता है के बारे में सोचने का प्रयोग करेंगे।

+0

अभी यह सिर्फ एक फ़ाइल सर्वर और एक सॉकेट.ओ सर्वर है, हालांकि आखिरकार मेरे पास आंदोलन अपडेट दिए गए खिलाड़ी पदों को निर्धारित करने के लिए गेम तर्क भी होगा और मुझे प्रत्येक क्लाइंट और अनुमानों के पिंग को देखने वाले अंतराल न्यूनीकरण तर्क की आवश्यकता होगी गेम स्टेट वे वर्तमान में मौजूदा डेटा से निर्णय ले रहे हैं। फास्ट-फॉरवर्ड समय पर कुछ तर्क होने के बाद, समय को रिवाइंड करने के लिए कुछ तर्क, खिलाड़ियों को स्थानांतरित करने के लिए कुछ तर्क, नेटवर्क डेटा को संभालने के लिए कुछ तर्क, और फाइलों को संभालने के लिए कुछ तर्क यह है कि मैं अलग-अलग फाइलों में अलग-अलग चीज़ों को अलग करना चाहता था। सिर्फ socket.io सामान नहीं। – stevendesu

+0

यह सिर्फ शुरुआत है - आपके द्वारा पोस्ट की गई फ़ाइलों के साथ। आप एक से अधिक 'var xxx = आवश्यकता (' ./ xxx ') कर सकते हैं; और अपने ऐप को कई फाइलों में विभाजित कर सकते हैं। मैं कल मोंगोडब conf में था और 10gen से किसी ने नोड/मोंगो/websockets (https://github.com/christkv/mongoman) पर आधारित एक गेम दिखाया है, वह सॉकेट पर बीएसओएन डेटा भेज रहा है और क्लाइंट पर डेटा डीकोड करता है - बनाता है क्लाइंट/सर्वर के बीच एक तेज संचार के लिए ... शायद यह आपके लिए दिलचस्प है !? – pkyeck

0

मैं एक और समाधान है। आप requ.js को मॉड्यूल बनाने और "ऐप" को तर्क के रूप में पास करने के लिए उपयोग कर सकते हैं। मॉड्यूल के भीतर आप socket.io शुरू कर सकते हैं और अपने सॉकेट व्यवस्थित कर सकते हैं।

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

मुझे आशा है कि:

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 में मॉड्यूल आप कुछ इस तरह कर सकते हैं।

+1

यदि कोई इसे पढ़ रहा है तो सोच रहा है, नहीं, बिलकुल कोई कारण नहीं है नोड के भीतर एएमडी का उपयोग करने के लिए। –

+0

यह सिर्फ एक विकल्प है, ऐसा करने का एकमात्र तरीका नहीं है –

1

मुझे इस पर भी एक दरार है और मैं परिणाम से काफी खुश हूं। स्रोत कोड के लिए https://github.com/hackify/hackify-server देखें।

संबंधित मुद्दे