2011-11-05 13 views
6

मैं नोडजेएस में बनाए गए अनुप्रयोगों को स्वतः तैनात करने के लिए एक मंच बनाने की कोशिश कर रहा हूं। प्रत्येक एप्लिकेशन को इन नियंत्रणों को नियंत्रित करने वाले नियंत्रण कक्ष से प्रारंभ और रोक दिया जा सकता है। जब एक आवेदन शुरू की है नियंत्रण कक्ष निम्नलिखित बातें करता है:बाल प्रक्रियाओं से हैंडल का सही ढंग से निपटान कैसे करें

  • एक बंदरगाह-बांधने की मशीन है कि रूट के रूप में चल रहा है से एक हैंडल अनुरोध। यह पोर्ट-बाइंडर नियंत्रण कक्ष का एक कांटा बच्चा है।
  • अब नियंत्रण कक्ष इस बंदरगाह पर अनुरोधों के लिए सुनता है। एक बार अनुरोध प्राप्त हो जाने पर यह क्लाइंट सॉकेट के हैंडल को उस एप्लिकेशन पर भेजता है जो नए अनुरोधों के लिए 'संदेश' ईवेंट पर सुन रहा है।
  • एक बार जब एप्लिकेशन को संकेत दिया जाता है तो नियंत्रण कक्ष अनुरोध और सॉकेट पर सभी नियंत्रण जारी करता है।
  • एप्लिकेशन जो करता है उसे करता है और अनुरोध और सॉकेट को रिलीज़ और बंद करता है।

यह सेटअप एक सर्वर को नीचे लाने की कोशिश करते समय छोड़कर, ठीक से काम करता है, जो अब आवश्यक नहीं है। हालांकि सर्वर 'करीबी' घटना को उत्सर्जित करता है, फिर भी यह कनेक्शन स्वीकार करता है, जो अंततः समय समाप्त हो जाता है क्योंकि कोई अनुरोध नहीं है लिस्टनर अब बाध्य है।

मुझे लगता है कि एक ऐसा संभाल है जिसे ठीक तरह से जारी नहीं किया जा रहा है और इस प्रकार सर्वर जाग रहा है।

पोर्ट बांधने की मशीन:

var options = { 
    http: require('http'), 
    https: require('https') 
}; 
process.on('message',function(data, handle) { 

    var port = data.port, 
      type = data.type, 
      server; 

    server = options[type].createServer(); 
    server.once('error', function(err) { 
     process.send({success: false, port: port, error: err}); 
    }); 
    server.listen(port,function(){ 
     var handle = server._handle; 

     process.send({success: true, port: port}, handle); 

     server.close(); 
     handle.close(); 
     server._handle = null; 
     handle = null; 
     server.removeAllListeners(); 
    }); 
}); 

नियंत्रण कक्ष:

var cp = require('child_process'), 
    app, 
    types = { 
     http: require('http'), 
     https: require('https') 
    }, 
    binder = cp.fork('./portbinder'); 

binder.on('message', function(data, handle) { 
    var server = types['http'].createServer(handler); 

    server.once('close', function() { 
     server._handle = null; 
     handle = null; 
    }); 
    server.listen(handle); 
}); 

function handler(req, resp) { 
    app = app || cp.fork('./application'), 
    socket = resp.socket, 

    _handle = socket._handle, 
    _req = {}, 
    _resp = {}, 
    _socket = {}; 

    // Copy transferable fields. 
    for(i in req) { 
     if(typeof req[i] != 'function' && i != 'socket' && i != 'connection' && i != 'client') { 
      _req[i] = req[i]; 
     } 
    } 

    for(i in resp) { 
     if(typeof resp[i] != 'function' && i != 'socket' && i != 'connection' && i != 'client') { 
      _resp[i] = resp[i]; 
     } 
    } 

    for(i in socket) { 
     if(typeof socket[i] != 'function' && 
      i != '_handle' && i != '_httpMessage' && 
      i != '_idlePrev' && i != '_idleNext' && i != 'server') { 
       _socket[i] = socket[i]; 
     } 
    } 

    // Send request to application. 
    app.send({ 
     type: 'request', 
     data: { 
      req: _req, 
      resp: _resp, 
      socket: _socket 
     } 
    }, _handle); 

    // Release the handle here without sending anything to the browser. 
    socket._write = function() {}; 
    resp.end(); 
    socket.destroy(); 
    socket._handle = null; 
    _handle = null; 
}; 

आवेदन:

आप मैं शून्य और सभी _handle गुण अलग करने कोशिश कर रहा हूँ देख सकते हैं मैं है, लेकिन सर्वर हैंडल बंदरगाह पर सुनना बंद नहीं करता है। जब मैं कंट्रोल पैनेल को एक अपवाद अपवाद करता हूं तो यह दुर्घटनाग्रस्त हो जाता है और बंदरगाह बांधने वाला भी ऐसा करता है। लेकिन एप्लिकेशन नोड प्रक्रिया से बाहर नहीं निकलता है और बंदरगाह बाध्य रहता है, इसलिए मैं यह कह रहा हूं कि मैं वहां कुछ ठीक से रिलीज़ नहीं कर रहा हूं, लेकिन मैं इसे खोजने में असमर्थ हूं।

पूरा सेटअप काम करता है, जब मैं इसे पूछता हूं तो यह सर्वर को बंद नहीं कर रहा है।

संपादित करें: मैं शायद नोट करना चाहिए कि मैं Node.js v0.5.10

+0

आप v0.6.0 के साथ करने की कोशिश की है? मेरा मानना ​​है कि वे बच्चे के लिए और अधिक कार्यक्षमता को शामिल किया है प्रक्रियाओं –

+0

स्थापित v0.6.0 आज, और समस्या अभी भी बनी हुई है। दस्तावेज़ कुछ भी नया वर्णन नहीं करते हैं, मैं बाद में स्रोत को देख रहा हूं, शायद यह दस्तावेज नहीं है। –

उत्तर

8

उपयोग कर रहा हूँ यह पता चला है के रूप में यह Node.js प्रलेखन कि इस समस्या के लिए नेतृत्व की एक अशुद्ध अर्थ है। मैं जिस ब्राउजर का उपयोग कर रहा था, उसी समय कनेक्शन के नए अनुरोधों को धक्का देने के लिए कनेक्शन को बनाए रखने के लिए कुछ समय के लिए खुले रहते हैं। नए कनेक्शन स्वीकार करने से

बंद हो जाता है सर्वर:

जब मैं एक server.close किया() मैं इन कनेक्शन को बंद करना पड़ा क्योंकि दस्तावेज़ कहते हैं कि उम्मीद है।

जैसा कि यह पता चला है, जीवित कनेक्शन बंद नहीं हैं, इसलिए ब्राउज़र तब तक अनुरोध करने में सक्षम था जब तक कनेक्शन खुला था, मुझे यह विचार दे रहा था कि सर्वर अभी भी कनेक्शन स्वीकार कर रहा है।

इसका समाधान इसे बंद करने के बाद आपके सर्वर पर अनुरोधकर्ता को दोबारा भेज रहा है। फिर जब आप कनेक्शन प्राप्त करते हैं, तो कुछ भी भेजने के बिना सॉकेट स्ट्रीम बंद करें। अब कोई नया अनुरोध संभाला नहीं जाएगा, और जैसे ही कनेक्शन के समय बंद हो जाएंगे और अंत में सर्वर पूरी तरह से बंद हो जाएगा। और इस प्रकार अन्य उपयोगों के लिए बंदरगाह को मुक्त करना।

server.close(); 
// Drop any new request immediately, while server ditches old connections. 
server.on('request', function(req, resp) { req.socket.end(); }); 
server.once('close', function(){ 
    // Remove the listeners after the server has shutdown for real. 
    server.removeAllListeners(); 
}); 

जगह मैं अपने कोड को साफ और संभाल रिलीज करने के लिए कोड को दूर कर सकता है में यह सुधार लाना। node.js कचरा कलेक्टर अब हैंडल ऑब्जेक्ट्स को सही तरीके से उठाता है और जब कनेक्शन मर जाता है, तो हैंडल भी करता है।

// All of this is no longer needed. 
socket._write = function() {}; 
socket.end(); 
socket.destroy(); 
socket._handle = null; 
handle = null; 
संबंधित मुद्दे