强制closuresnode.js http服务器中的所有连接

我有一个http服务器创build使用:

var server = http.createServer()

我想closures服务器。 大概我会这样做,通过调用:

server.close()

但是,这只会阻止服务器接收任何新的http连接。 它没有closures任何仍然打开。 http.close()接受callback,并且在所有打开的连接实际上断开之前,该callback不会被执行。 有没有办法强制closures一切?

问题的根源在于我有Mochatesting,在他们的设置( beforeEach() )中启动一个http服务器,然后在他们的拆卸( afterEach() )中closures它。 但是,由于只调用server.close()不会完全closures,后续的http.createServer()通常会导致EADDRINUSE错误。 等待close()完成也不是一个选项,因为打开连接可能需要很长时间才能超时。

我需要一些方法来强制closures连接。 我能够做到这一点客户端,但强迫所有的testing连接closures,但我宁愿做服务器端,即只告诉http服务器硬closures所有套接字。

你需要

  1. 订阅服务器的connection事件并将打开的套接字添加到数组中
  2. 通过订阅它们的close事件来跟踪打开的套接字,并从arrays中删除封闭的套接字
  3. 当您需要终止服务器时,调用所有剩余的打开的套接字上的destroy

您也有机会在subprocess中运行服务器,并在需要时退出该进程。

对于其他谁绊倒这个问题的参考, https://github.com/isaacs/server-destroy库提供了一个简单的方法来destroy()服务器(使用Ege描述的方法)。

我通常使用类似的东西:

 var express = require('express'); var server = express(); /* a dummy route */ server.get('/', function (req, res) { res.send('Hello World!'); }); /* handle SIGTERM and SIGINT (ctrl-c) nicely */ process.once('SIGTERM', end); process.once('SIGINT', end); var listener = server.listen(8000, function(err) { if (err) throw err; var host = listener.address().address; var port = listener.address().port; console.log('Server listening at http://%s:%s', host, port); }); var lastSocketKey = 0; var socketMap = {}; listener.on('connection', function(socket) { /* generate a new, unique socket-key */ var socketKey = ++lastSocketKey; /* add socket when it is connected */ socketMap[socketKey] = socket; socket.on('close', function() { /* remove socket when it is closed */ delete socketMap[socketKey]; }); }); function end() { /* loop through all sockets and destroy them */ Object.keys(socketMap).forEach(function(socketKey){ socketMap[socketKey].destroy(); }); /* after all the sockets are destroyed, we may close the server! */ listener.close(function(err){ if(err) throw err(); console.log('Server stopped'); /* exit gracefully */ process.exit(0); }); } 

就像EgeÖzcan所说的那样,只需在连接事件中收集套接字,并在closures服务器时将其销毁。

我的方法来自这一个 ,它基本上做了@EgeÖzcan说。

唯一的补充是我设置了一个路由来closures我的服务器,因为节点没有从我的terminal获取信号( 'SIGTERM''SIGINT' )。

那么,节点在做node whatever.js时候从terminal上得到了信号,但是当把这个任务委托给一个脚本(比如package.json中的'start'脚本 – > npm start )时,它没有被Ctrl+C ,所以这种方法为我工作。

请注意我在Cygwin之下,并​​且在这之前杀死一台服务器意味着closuresterminal并重新打开它。

另外请注意,我正在使用快递路由的东西。

 var http=require('http'); var express= require('express'); var app= express(); app.get('/', function (req, res) { res.send('I am alive but if you want to kill me just go to <a href="/exit">/exit</a>'); }); app.get('/exit', killserver); var server =http.createServer(app).listen(3000, function(){ console.log('Express server listening on port 3000'); /*console.log(process);*/ }); // 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); }); // close the server and destroy all the open sockets function killserver() { console.log("U killed me but I'll take my revenge soon!!"); // 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(); } };