2013-01-31 36 views
36

मेरे पास एक Node.js एप्लिकेशन है जिसमें http (s) सर्वर है।मैं तुरंत Node.js http (सर्वर) सर्वर को कैसे बंद कर सकता हूं?

एक विशिष्ट मामले में, मुझे इस सर्वर को प्रोग्रामेटिक रूप से बंद करने की आवश्यकता है। मैं वर्तमान में जो कर रहा हूं वह close() फ़ंक्शन को कॉल कर रहा है, लेकिन इससे मदद नहीं मिलती है, क्योंकि यह पहले खत्म होने के लिए किसी भी जीवित कनेक्शन के लिए इंतजार कर रहा है।

तो, मूल रूप से, यह सर्वर को बंद करता है, लेकिन केवल 120 सेकंड के न्यूनतम प्रतीक्षा समय के बाद। लेकिन मैं चाहता हूं कि सर्वर तुरंत बंद हो जाए - भले ही इसका मतलब वर्तमान में संभाले गए अनुरोधों के साथ टूटना है।

क्या मैं ऐसा नहीं कर सकते एक सरल

process.exit(); 

के रूप में सर्वर अनुप्रयोग का ही हिस्सा है, और आवेदन के बाकी चलता रहना चाहिए। जो मैं खोज रहा हूं वह अवधारणात्मक रूप से कुछ है जैसे server.destroy(); या ऐसा कुछ।

मैं इसे कैसे प्राप्त कर सकता हूं?

पीएस: कनेक्शन के लिए रख-रखाव का समय आमतौर पर आवश्यक है, इसलिए यह इस समय कम करने का एक व्यवहार्य विकल्प नहीं है।

+2

एक मुद्दा नोड में इस बात के लिए नहीं है: https://github.com/nodejs/node/issues/2642 – hunterloftis

उत्तर

54

चाल है कि आप सर्वर के connection घटना है जो आप नए कनेक्शन की सॉकेट देता है की सदस्यता के लिए की जरूरत है । आपको server.close() कहने के बाद सीधे इस सॉकेट को याद रखना होगा और उस सॉकेट को socket.destroy() का उपयोग करके नष्ट करना होगा।

इसके अतिरिक्त, आपको सॉकेट की close ईवेंट को सरणी से निकालने के लिए सुनना होगा यदि यह स्वाभाविक रूप से छोड़ देता है क्योंकि इसका लाइव-टाइम टाइमआउट समाप्त हो जाता है।

मैं एक छोटा सा नमूना आवेदन आप इस व्यवहार प्रदर्शित करने के लिए उपयोग कर सकते हैं लिखा है:

// Create a new server on port 4000 
var http = require('http'); 
var server = http.createServer(function (req, res) { 
    res.end('Hello world!'); 
}).listen(4000); 

// Maintain a hash of all connected sockets 
var sockets = {}, nextSocketId = 0; 
server.on('connection', function (socket) { 
    // Add a newly connected socket 
    var socketId = nextSocketId++; 
    sockets[socketId] = socket; 
    console.log('socket', socketId, 'opened'); 

    // Remove the socket when it closes 
    socket.on('close', function() { 
    console.log('socket', socketId, 'closed'); 
    delete sockets[socketId]; 
    }); 

    // Extend socket lifetime for demo purposes 
    socket.setTimeout(4000); 
}); 

// Count down from 10 seconds 
(function countDown (counter) { 
    console.log(counter); 
    if (counter > 0) 
    return setTimeout(countDown, 1000, counter - 1); 

    // Close the server 
    server.close(function() { console.log('Server closed!'); }); 
    // Destroy all open sockets 
    for (var socketId in sockets) { 
    console.log('socket', socketId, 'destroyed'); 
    sockets[socketId].destroy(); 
    } 
})(10); 

असल में, क्या यह होता है एक नया HTTP सर्वर शुरू, 10 0 से गिनती, और बाद सर्वर बंद करने के लिए है दस पल। यदि कोई कनेक्शन स्थापित नहीं किया गया है, तो सर्वर तुरंत बंद हो जाता है।

यदि कोई कनेक्शन स्थापित किया गया है और यह अभी भी खुला है, तो यह नष्ट हो गया है। यदि यह स्वाभाविक रूप से स्वाभाविक रूप से मर चुका है, तो उस समय केवल एक संदेश मुद्रित किया जाता है।

+2

'socket.on ("बंद करें" , ...) 'socket.once (" बंद करें ", ...)'? – jpillora

+0

मुझे लगता है, हाँ :-) –

1

मेरा सबसे अच्छा अनुमान मैन्युअल रूप से कनेक्शन को मारना होगा (यानी जबरन बंद करने के लिए इसे सॉकेट करें)।

आदर्श रूप में, यह सर्वर के आंतरिक में खोदकर और हाथों से अपने सॉकेट बंद करके किया जाना चाहिए। वैकल्पिक रूप से, एक एक खोल कमान एक ही है कि चला सकते हैं (सर्वर प्रदान की उचित विशेषाधिकार & सी है।)

+1

सवाल यह है कि: मैं किसी भी अनियंत्रित व्यवहार के बिना कनेक्शन के सॉकेट का उपयोग कैसे करूं? –

+0

मूल रूप से, आपके उत्तर ने मुझे सही रास्ते पर जाने में मदद की। मेरा जवाब देखें कि मैंने इसे कैसे हल किया (बिना किसी अनियंत्रित व्यवहार का उपयोग किए; ;))। वैसे भी, सही विचार के लिए +1 :-) –

+0

यही कारण है कि मैं अस्पष्ट था। यह आपके द्वारा उपयोग किए जाने वाले रैपर लाइब्रेरी (उदाहरण के लिए, 'एक्सप्रेस') और नोड.जेएस/पुस्तकालयों का कौन सा संस्करण उपयोग कर रहा है (एपीआई समय के साथ अलग-अलग) –

3

जैसा कि अन्य ने कहा है, समाधान सभी खुले सॉकेट का ट्रैक रखना और उन्हें मैन्युअल रूप से बंद करना है। मेरा नोड पैकेज killable आपके लिए यह कर सकता है। एक उदाहरण (एक्सप्रेस का उपयोग करते हुए, लेकिन आप किसी भी http.server उदाहरण पर इस्तेमाल के killable कॉल कर सकते हैं):

6

https://github.com/isaacs/server-destroy पुस्तकालय destroy() व्यवहार प्रश्न में वांछित के साथ एक सर्वर के लिए एक आसान तरीका प्रदान करता है (खोला कनेक्शन पर नज़र रखने और नष्ट करके उनमें से प्रत्येक सर्वर को नष्ट कर देता है, जैसा कि अन्य उत्तरों में वर्णित है)।

+0

एक बनाए रखा विकल्प, https://github.com/thedillonb/http-shutdown और https://github.com/hunterloftis/stoppable। – Gajus

6

यदि आपको सर्वर बंद करने के बाद प्रक्रिया को जीवित रखने की आवश्यकता है, तो Golo Roden का समाधान शायद सबसे अच्छा है।

लेकिन अगर आप प्रक्रिया का एक सुंदर शटडाउन के हिस्से के रूप सर्वर को बंद कर रहे हैं, तो आप सिर्फ यह की जरूरत है:

var server = require('http').createServer(myFancyServerLogic); 

server.on('connection', function (socket) {socket.unref();}); 
server.listen(80); 

function myFancyServerLogic(req, res) { 
    req.connection.ref(); 

    res.end('Hello World!', function() { 
     req.connection.unref(); 
    }); 
} 

असल में, सॉकेट कि आपके सर्वर का उपयोग करता है केवल प्रक्रिया को जीवित रखने होगा, जबकि वे वास्तव में एक अनुरोध की सेवा कर रहे हैं। हालांकि वे वहां बस बैठे हैं (एक Keep-Alive कनेक्शन की वजह से), server.close() पर कॉल प्रक्रिया को बंद कर देगा, जब तक प्रक्रिया को जीवित रखने के अलावा कुछ और नहीं है। अगर आपको बंद करने के बाद अन्य चीजों को करने की ज़रूरत है, तो आपके शानदार शट डाउन के हिस्से के रूप में, आप अपनी सुंदर शट डाउन प्रक्रियाओं को समाप्त करने के लिए process.on('beforeExit', callback) में हुक कर सकते हैं।

+0

यह वास्तव में एक अच्छा विचार दिखता है, लेकिन किसी कारण से यह नोड 'v7.10.0' और एक्सप्रेस' 4.15.2' के साथ काम नहीं कर रहा है। क्या आपने इसका परीक्षण किया है? –

8

मुझे कनेक्शन का ट्रैक रखने या उन्हें बंद करने के लिए मजबूर किए बिना ऐसा करने का कोई तरीका मिला। मुझे यकीन नहीं है कि यह नोड संस्करणों में कितना विश्वसनीय है या यदि इसके लिए कोई नकारात्मक परिणाम हैं लेकिन ऐसा लगता है कि मैं जो कर रहा हूं उसके लिए यह बिल्कुल ठीक काम करता है। यह चाल विधि को कॉल करने के ठीक बाद setImmediate का उपयोग करके "बंद" ईवेंट को उत्सर्जित करना है। यह बहुत तरह काम करता है:

server.close(callback); 
setImmediate(function(){server.emit('close')}); 

कम से कम मेरे लिए, इस बंदरगाह को मुक्त कराने के समाप्त होता है, ताकि मैं समय कॉलबैक कहा जाता है (जो काफी तुरन्त है) द्वारा एक नया HTTP (एस) सेवा शुरू कर सकते हैं। मौजूदा कनेक्शन खुले रहेंगे। मैं लेट्स एन्क्रिप्ट प्रमाणपत्र को नवीनीकृत करने के बाद स्वचालित रूप से HTTPS सेवा को पुनरारंभ करने के लिए इसका उपयोग कर रहा हूं।

-4

process.exit (कोड); // सफलता के लिए कोड 0 और 1 के लिए

+1

सवाल यह कहता है कि 'process.exit()' एक विकल्प नहीं है। –

1

फिर भी एक और NodeJS पैकेज असफल बंद की हत्या कनेक्शन प्रदर्शन करने के लिए: http-shutdown, जो यथोचित लिखने के समय बनाए रखा लगता है (सितम्बर 2016) और NodeJS 6.x पर मेरे लिए काम किया

प्रलेखन

प्रयोग

वर्तमान में इस पुस्तकालय का उपयोग करने के दो तरीके हैं से

। पहले सर्वर वस्तु का स्पष्ट रैपिंग है:

// Create the http server 
var server = require('http').createServer(function(req, res) { 
    res.end('Good job!'); 
}); 

// Wrap the server object with additional functionality. 
// This should be done immediately after server construction, or before you start listening. 
// Additional functionailiy needs to be added for http server events to properly shutdown. 
server = require('http-shutdown')(server); 

// Listen on a port and start taking requests. 
server.listen(3000); 

// Sometime later... shutdown the server. 
server.shutdown(function() { 
    console.log('Everything is cleanly shutdown.'); 
}); 

दूसरा परोक्ष सर्वर ऑब्जेक्ट के लिए प्रोटोटाइप कार्यक्षमता जोड़ने है:

// .extend adds a .withShutdown prototype method to the Server object 
require('http-shutdown').extend(); 

var server = require('http').createServer(function(req, res) { 
    res.end('God job!'); 
}).withShutdown(); // <-- Easy to chain. Returns the Server object 

// Sometime later, shutdown the server. 
server.shutdown(function() { 
    console.log('Everything is cleanly shutdown.'); 
});