1
我正在通過代理服務器將數據從客戶端套接字發送到http服務器。當我將這些數據從代理服務器發佈到http時,一切正常,但如果關閉http服務器,代理服務器就會死亡。node.js代理服務器發佈到http服務器,並在http服務器關閉時死亡
我以爲post.end()函數會關閉請求,但顯然不是?!我需要做一些回撥魔術嗎?
我附加我下面的控制檯輸出,但這裏的步驟簡要說明:
- 啓動服務器:節點--harmony_weakmaps server.js
- 開始API(HTTP服務器):節點API的.js
- 啓動客戶端(遠程登錄本地主機5280)
- 客戶端連接消息:{ 「M」: 「連接」, 「ID」: 「123」}
- 客戶端消息以API:{ 「M」: 「x」,「id」:「123」}
- 殺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)
控制檯(客戶端,遠程登錄):
>>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 se的tcp-ip服務器rver):
// 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);