मेरे पास एक प्रॉक्सी सर्वर है जो ग्राहकों का एक समूह प्रबंधित करता है और अन्य http सर्वर से भी बात करता है। संदेशों को आगे और आगे पोस्ट किया जाता है और ग्राहकों को निर्देशित किया जाता है। ग्राहक टाइमआउट कर सकते हैं और कर सकते हैं, और सर्वर में दिल की धड़कन का फ़ंक्शन होता है (जो प्रत्येक एन सेकेंड को दोहराता है) जो क्लाइंट के मानचित्र में मौजूद सभी क्लाइंट्स को दिल की धड़कन भेजता है।node.js सॉकेट अपवाद ETIMEDOUT पढ़ें - मैं इसे ठीक से कैसे पकड़ूं? टाइमआउट लिखने के बारे में क्या?
मुझे 'ETIMEDOUT' अपवाद मिलता है जब दिल की धड़कन उस क्लाइंट से बात करने का प्रयास करती है जो अब कनेक्ट नहीं है लेकिन कौन सा सॉकेट अभी भी सक्रिय है। मैंने सैद्धांतिक रूप से सॉकेट कनेक्शन के टाइमआउट को इस सिद्धांत के साथ सेट करने की कोशिश की कि सिद्धांत के साथ मेरा सॉकेट इवेंट हैंडलर इसे पकड़ लेगा (इवेंट हैंडलर टीसीपी सर्वर भाग में है), लेकिन ऐसा नहीं हुआ। मरने के लिए कई दिल की धड़कन लगती है।
समस्या का हिस्सा निश्चित रूप से node.js कोड को कैसे विकसित करना है, इसकी समझ की कमी है, इसलिए यदि आपके पास कोई सुझाव है, तो मैं उनकी बहुत सराहना करता हूं।
एक और सवाल यह है कि क्या समय-समय पर पढ़ने और लिखने को संभालना संभव है, या कम से कम उन्हें बाहर तोड़ना संभव है। मैं वास्तव में क्या करना चाहता हूं कि मेरे दिल की धड़कन समारोह टीसीपी सर्वर का हिस्सा हो और केवल दिल की धड़कन भेज दें यदि उसने क्लाइंट से एन सेकंड में नहीं सुना है, और केवल एक बार इस दिल की धड़कन भेज दें। अगर हमें टाइमआउट मिलता है, तो हम सॉकेट को मार देते हैं, अन्यथा हम फिर से इंतजार करते हैं।
धन्यवाद!
>>$ node --harmony-weakmaps server.js
Heartbeat: Sat Feb 18 2012 08:34:40 GMT+0000 (UTC)
{
sending keep_alive to id:00:00:00:00:00:10 socket:[object Object]
}
socket:received data: {"id":"00:00:00:00:00:10","m":"keep_alive","success":"true"}
Heartbeat: Sat Feb 18 2012 08:35:40 GMT+0000 (UTC)
{
sending keep_alive to id:00:00:00:00:00:10 socket:[object Object]
}
socket:received data: {"id":"00:00:00:00:00:10","m":"keep_alive","success":"true"}
node.js:201
throw e; // process.nextTick error, or 'error' event on first tick
^
Error: read ETIMEDOUT
at errnoException (net.js:642:11)
at TCP.onread (net.js:375:20)
हार्टबीट समारोह है कि समय समाप्ति से चलाता है:
console.log("Starting heartbeat");
var beat_period = 60;
setInterval(function() {
if(Object.keys(id2socket).length != 0){
console.log("Heartbeat: " + new Date());
//for (var key in id2socket) {
// console.log("\t"+key+"->"+id2socket[key]);
//}
console.log("{");
for(var id in id2socket) {
var socket = id2socket[id];
// don't want sockets to time out
socket.setTimeout(2000); // for heartbeat, set the timeout
try {
console.log("\tsending keep_alive to id:"+id+" socket:"+id2socket[id]);
socket.write('{"m":"keep_alive"}\r\n');
} catch(Error) {
console.log("Heartbeat:Cannot find id:"+id);
removeSocketFromMap(id,socket);
// TODO: send message to API
}
socket.setTimeout(0); // no timeout
}
console.log("}");
}
}, beat_period * 1000);
server.js:
// Launch Instructions
// node --harmony-weakmaps server.js
var net = require('net'); // tcp-server
var http = require("http"); // http-server
var querystring = require('querystring');
// Map of sockets to clients
var id2socket = new Object;
var socket2id = new WeakMap; // allows us to use object as key to hash
// Test for client:
// {"id":"123","m":"add"} // establishes connection and puts client into id2socket map
// {"id":"123","m":"test"} // sends a message through to API
// HTTP:POST outbound function
// http://www.theroamingcoder.com/node/111
function postOut(dataToPost){
try{
console.log("postOut msg:"+JSON.stringify(dataToPost));
} catch (Error) {
console.log("postOut error:"+Error);
}
var post_domain = '127.0.0.1';
var post_port = 80;
var post_path = '/cgi-bin/index3.py';
var post_data = querystring.stringify({
'act' : 'testjson',
'json' : JSON.stringify(dataToPost)
});
console.log("post_data:"+post_data);
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:data: ' + chunk);
});
});
// Handle various issues
post_req.on('error', function(error) {
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:response:"+response);
});
// write parameters to post body
post_req.write(post_data);
post_req.end();
}
function removeSocketFromMap(id,socket){
console.log("removeSocketFromMap socket:"+socket+" id:"+id);
delete id2socket[id];
socket2id.delete(socket);
//TODO: print map???
console.log("socketmap {");
for (var key in id2socket) {
console.log("\t"+key+"->"+id2socket[key]);
}
console.log("}");
}
// Setup a tcp server
var server_plug = net.createServer(
function(socket) {
// Event handlers
socket.addListener("connect", function(conn) {
console.log("socket:connection from: " + socket.remoteAddress + ":" + socket.remotePort + " id:"+socket.id);
});
socket.addListener("data", function(data) {
console.log("socket:received data: " + data);
var request = null;
try {
request = JSON.parse(data);
} catch (SyntaxError) {
console.log('Invalid JSON:' + data);
socket.write('{"success":"false","response":"invalid JSON"}\r\n');
}
if(request!=null){
response = request; // set up the response we send back to the client
if(request.m=="keep_alive"){ // HACK for keep alive
// Do nothing
} else if(request.m !== undefined && request['id'] !== undefined){ // hack on 'id', id is js obj property
if(request.m == 'connect_device' || request.m == 'add'){
console.log("associating uid " + request['id'] + " with socket " + socket);
id2socket[request['id']] = socket;
socket2id.set(socket, request['id']);
}
postOut(request);
socket.write(JSON.stringify(response)+"\r\n");
} else if(request['id'] !== undefined){
postOut(request);
socket.write(JSON.stringify(response)+"\r\n");
} else {
response['content'] = "JSON doesn't contain m or id params";
socket.write(JSON.stringify(response)+"\r\n");
}
} else {
console.log("null request");
}
});
socket.on('end', function() {
id = socket2id.get(socket);
console.log("socket:disconnect by id " + id);
removeSocketFromMap(id,socket);
socket.destroy();
});
socket.on('timeout', function() {
id = socket2id.get(socket);
console.log('socket:timeout by id ' + id);
removeSocketFromMap(id,socket);
socket.destroy();
});
// handle uncaught exceptions
socket.on('uncaughtException', function(err) {
id = socket2id.get(socket);
console.log('socket:uncaughtException by id ' + id);
removeSocketFromMap(id,socket);
socket.destroy();
});
}
);
server_plug.on('error', function (error) {
console.log('server_plug:Error: ' + error);
});
// 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.on('error', function(err){
console.log("server_http:error: "+err);
})
request.addListener("data", function(chunk) {
request.content += chunk;
});
request.addListener("end", function() {
console.log("server_http:request_received");
try {
var json = querystring.parse(request.content);
console.log("server_http:received_post {");
for(var foo in json){
console.log("\t"+foo+"->"+json[foo]);
}
console.log("}");
// Send json message content to socket
if(json['json']!=null && json['id']!=null){
id = json['id'];
try {
var socket = id2socket[id];
socket.write(json['json']+"\r\n");
} catch (Error) {
console.log("Cannot find socket with id "+id);
} finally {
// respond to the incoming http request
response.end();
// TODO: This should really be in socket.read!
}
}
} catch(Error) {
console.log("JSON parse error: "+Error)
}
});
request.on('end', function() {
console.log("http_request:end");
});
request.on('close', function() {
console.log("http_request:close");
});
}
);
server_http.on('error', function (error) {
console.log('server_http:Error: ' + error);
});
// Heartbeat function
console.log("Starting heartbeat");
var beat_period = 60;
setInterval(function() {
if(Object.keys(id2socket).length != 0){
console.log("Heartbeat: " + new Date());
//for (var key in id2socket) {
// console.log("\t"+key+"->"+id2socket[key]);
//}
console.log("{");
for(var id in id2socket) {
var socket = id2socket[id];
// don't want sockets to time out
socket.setTimeout(2000); // for heartbeat, set the timeout
try {
console.log("\tsending keep_alive to id:"+id+" socket:"+id2socket[id]);
socket.write('{"m":"keep_alive"}\r\n');
} catch(Error) {
console.log("Heartbeat:Cannot find id:"+id);
removeSocketFromMap(id,socket);
// TODO: send message to API
}
socket.setTimeout(0); // no timeout
}
console.log("}");
}
}, beat_period * 1000);
// Fire up the servers
//var HOST = '127.0.0.1'; // just local incoming connections
var HOST = '0.0.0.0'; // allows access to all external IPs
var PORT = 5280;
var PORT2 = 9001;
// 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);
संपादित करें:
मैं बनाम (घटना, कॉलबैक) .on प्रयोग करना चाहिए .onlistener (घटना, कॉलबैक)?
अद्यतन:
कि काम नहीं किया, मैं सामान tcp_server में सभी add_listener को .on के रूप में दिल की धड़कन में बदल दिया है। अभी भी त्रुटियों को पकड़ नहीं लिया और उड़ा दिया और कहा कि मैंने बहुत सारे श्रोताओं को जोड़ा है।
मुझे एक ही समस्या है, ETIMEDOUT अपवाद नहीं पकड़ सकता है। क्या आपने इसे हल किया? – takluiper