node.js代理服务器发送到http服务器,并在http服务器closures时终止

我通过代理服务器将数据从客户端套接字发送到http服务器。 当我从代理服务器发布这个数据到http,一切工作正常,但如果我closureshttp服务器,代理服务器死亡。

我以为post.end()函数会closures请求,但显然不是?! 我必须做一些callback魔术吗?

我附上了我的控制台输出,下面是对这些步骤的简要说明:

  1. 启动服务器:节点–harmony_weakmaps server.js
  2. 启动API(http服务器):节点api.js
  3. 启动一个客户端(telnet localhost 5280)
  4. 客户端连接消息:{“m”:“connect”,“id”:“123”}
  5. 客户端消息给api:{“m”:“x”,“id”:“123”}
  6. 杀死API进程 – 它爆炸了

控制台(服务器):

>>node --harmony_weakmaps server.js Starting heartbeat TCP server listening on 127.0.0.1:5280 HTTP server listening on 127.0.0.1:9002 Connection from 127.0.0.1:49356 id:undefined received data: {"m":"connect","id":"123"} id: 123 m: connect associating uid 123 with socket [object Object] Heartbeat Time: Tue Feb 14 2012 15:27:08 GMT-0800 (PST) received data: {"m":"x","id":"123"} id: 123 m: x Invalid JSON:{"m":"x","id":"123"} events.js:48 throw arguments[1]; // Unhandled 'error' event ^ Error: socket hang up at createHangUpError (http.js:1104:15) at Socket.onend (http.js:1181:27) at TCP.onread (net.js:369:26) 

控制台(客户端,远程login):

 >>telnet localhost 5280 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. >>{"m":"connect","id":"123"} {"m":"connect","id":"123","success":"true"} {"m":"pulse"} >>{"m":"x","id":"123"} {"success":"false","response":"invalid JSON"} Connection closed by foreign host. 

控制台(API):

 >>node api.js API (HTTP server) listening on 127.0.0.1:8081 Request received: m=x&id=123&success=true id: 123 m: x // Then I close it (^C) 

server.js(将数据从套接字发布到http服务器的tcp-ip服务器):

 // Launch Instructions // node --harmony server.js var net = require('net'); // tcp-server var http = require("http"); // http-server // Map of sockets to devices var id2socket = new Object; var socket2id = new WeakMap; // allows us to use object as key to hash // HTTP:POST outbound function // http://www.theroamingcoder.com/node/111 function postOut(dataToPost){ var querystring = require('querystring'); var http = require('http'); var post_domain = 'localhost'; var post_port = 8081; var post_path = '/'; var post_data = querystring.stringify(dataToPost); var post_options = { host: post_domain, port: post_port, path: post_path, method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': post_data.length } }; var post_req = http.request(post_options, function(res) { res.setEncoding('utf8'); res.on('data', function (chunk) { console.log('Response: ' + chunk); }); }); // write parameters to post body post_req.write(post_data); post_req.end(); request.on("response", function (response) { console.log(response); }); } function removeSocketFromMap(id,socket){ console.log("removeSocketFromMap socket:"+socket+" id:"+id); delete id2socket[id]; socket2id.delete(socket); //TODO: print map??? } // Setup a tcp server var server_plug = net.createServer( function(socket) { // Event handlers socket.addListener("connect", function(conn) { console.log("Connection from " + socket.remoteAddress + ":" + socket.remotePort + " id:"+socket.id ); }); socket.addListener("data", function(data) { console.log("received data: " + data); try { request = JSON.parse(data); response = request; if(request.m !== undefined && request['id'] !== undefined){ // hack on 'id', id is js obj property console.log("id: "+request['id']); console.log("m: "+request.m); if(request.m == 'connect'){ console.log("associating uid " + request['id'] + " with socket " + socket); id2socket[request['id']] = socket; socket2id.set(socket, request['id']); response.success = 'true'; } else { response.success = 'true'; postOut(request) } } socket.write(JSON.stringify(response)); } catch (SyntaxError) { console.log('Invalid JSON:' + data); socket.write('{"success":"false","response":"invalid JSON"}'); } }); socket.on('end', function() { id = socket2id.get(socket); console.log("socket disconnect by id " + id); removeSocketFromMap(id,socket); }); socket.on('timeout', function() { console.log('socket timeout'); }); } ); // Setup http server var server_http = http.createServer( // Function to handle http:post requests, need two parts to it // http://jnjnjn.com/113/node-js-for-noobs-grabbing-post-content/ function onRequest(request, response) { request.setEncoding("utf8"); request.content = ''; request.addListener("data", function(chunk) { request.content += chunk; }); request.addListener("end", function() { console.log("Request received: "+request.content); try { var json = JSON.parse(request.content); var id = json['id']; var m = json['m']; console.log("id: "+id); console.log("m: "+m); // TODO: refactor this into another function try { var socket = id2socket[id]; socket.write('{"m":"post"}'); } catch (Error) { console.log("Cannot find socket with id "+id); } } catch(Error) { console.log("JSON parse error: "+Error) } }); } ); // Heartbeat function console.log("Starting heartbeat"); var beat_period = 20; setInterval(function() { console.log("Heartbeat Time: " + new Date()); for(var id in id2socket) { var socket = id2socket[id]; try { socket.write('{"m":"pulse"}'); } catch(Error) { removeSocketFromMap(id,socket); } } }, beat_period * 1000); // Fire up the servers var HOST = '127.0.0.1'; var PORT = 5280; var PORT2 = 9002; // accept tcp-ip connections server_plug.listen(PORT, HOST); console.log("TCP server listening on "+HOST+":"+PORT); // accept posts server_http.listen(PORT2); console.log("HTTP server listening on "+HOST+":"+PORT2); 

api.js(http服务器):

 var http = require("http"); // http-server var querystring = require('querystring'); // Setup http server var server_http = http.createServer( // Function to handle http:post requests, need two parts to it // http://jnjnjn.com/113/node-js-for-noobs-grabbing-post-content/ function onRequest(request, response) { request.setEncoding("utf8"); request.content = ''; request.addListener("data", function(chunk) { request.content += chunk; }); request.addListener("end", function() { console.log("Request received: "+request.content); try { // Parse incoming JSON var json = querystring.parse(request.content); var id = json['id']; var m = json['m']; console.log("id: "+id); console.log("m: "+m); } catch(Error) { console.log("JSON parse error: "+Error) } }); } ); // Fire up the servers var HOST = '127.0.0.1'; var PORT = 8081; server_http.listen(PORT); console.log("API (HTTP server) listening on "+HOST+":"+PORT); 

愚蠢的我,我不能在节点中适当的error handling的速度。 修复postOut()做了诀窍:

 function postOut(dataToPost){ var querystring = require('querystring'); var http = require('http'); var post_domain = 'localhost'; var post_port = 8081; var post_path = '/'; var post_data = querystring.stringify(dataToPost); var post_options = { host: post_domain, port: post_port, path: post_path, method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': post_data.length } }; var post_req = http.request(post_options, function(res) { res.setEncoding('utf8'); res.on('data', function (chunk) { console.log('Response: ' + chunk); }); }); // Handle various issues post_req.on('error', function(error) { // <-------------------------------- Yeah Buddy!!! console.log('ERROR' + error.message); // If you need to go on even if there is an error add below line //getSomething(i + 1); }); post_req.on("response", function (response) { console.log(response); }); // write parameters to post body post_req.write(post_data); post_req.end(); request.on("response", function (response) { console.log(response); }); }