强制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所有套接字。
你需要
- 订阅服务器的
connection
事件并将打开的套接字添加到数组中 - 通过订阅它们的
close
事件来跟踪打开的套接字,并从arrays中删除封闭的套接字 - 当您需要终止服务器时,调用所有剩余的打开的套接字上的
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(); } };
- node.js请求和restify客户端有什么区别?
- Koa的`ctx.status`没有被发送到客户端
- Nodejs:在使用setuid / setgid之后在端口80上监听
- websocket与http模块一起工作,但不能与express(node.js)
- 在nodejs中parsingchunked-encoded http响应的最好方法是什么?
- Node.js Cluster + Express总是调用同一个worker
- 如何在node.js中没有express服务器的情况下实现Android Deeplink
- 错误:ENOENT,没有这样的文件或目录节点JS
- Nodejs在一个函数中循环http请求