2012-02-15 114 views
1

我正在通過代理服務器將數據從客戶端套接字發送到http服務器。當我將這些數據從代理服務器發佈到http時,一切正常,但如果關閉http服務器,代理服務器就會死亡。node.js代理服務器發佈到http服務器,並在http服務器關閉時死亡

我以爲post.end()函數會關閉請求,但顯然不是?!我需要做一些回撥魔術嗎?

我附加我下面的控制檯輸出,但這裏的步驟簡要說明:

  1. 啓動服務器:節點--harmony_weakmaps server.js
  2. 開始API(HTTP服務器):節點API的.js
  3. 啓動客戶端(遠程登錄本地主機5280)
  4. 客戶端連接消息:{ 「M」: 「連接」, 「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) 

控制檯(客戶端,遠程登錄):

>>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); 

回答

1

我傻,我達不到對正確的錯誤在節點的處理速度。修復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); 
    }); 
}