Sam Sam - 3 months ago 8
Node.js Question

net socket - determining which request is currently being responded to under socket.on("data")

I'm trying to write a custom http get function for use in node.js, using keep-alive requests. I'm going to be sending multiple requests through to a single host through a single TCP socket at the same time. How am I able to determine which response is currently having data emitted via

socket.on("data")
? Is each request handled one at a time, or is it possible that multiple requests end up responding with data at the same time? If that is not an issue and only one request's data is emitted through
socket.on("data")
at a time, how can I determine exactly which request is being responded to, and when that request has completed returning its data, how do I execute the specific callback for that request?

Here is my code at the moment:

var net = require("net");
var clients = {};
function get(url, callback) {
var protocol = url.split("://")[0];
var host = url.split("://")[1].split("/")[0];
var path = "/"+(url.split("://")[1]).split(/\/(.+)?/)[1];
var client = clients[host];
function loadPage(data) {
var rawRequest = "GET "+url+" HTTP/1.1\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.80 Safari/537.36\nhost: "+host+"\nCookie: \ncontent-length: 0\nConnection: keep-alive\r\n\r\n";
client.socket.write(rawRequest);
}
if (!client) {
clients[host] = {
socket:new net.Socket()
callbacks:[]
}
client = clients[host];
client.socket.connect(80, host, function() {
loadPage();
}
}
loadPage();
}

Answer

If you are sending multiple requests and receiving multiple responses over the same socket and you have no guarantee that the responses are coming back in order, then the only way to identify which response goes with which request is to tag them with a unique ID in the request (likely with a query parameter or a custom header) and have the server you are contacting include that specific tag in the response.

Then, you can identify which response is which from the tag. When, you send a request, you generate a new unique request ID and add it and the callback that goes with it to a Map. Then, when you get a response, you look at the uniqueID in the response, look it up in the Map and then call the callback associated with that uniqueID.

There is no other way to know which response goes with which request given the constraints. You have to artificially create a mapping between a request and a response and you need to responding server to cooperate by returning the uniqueID in order to do that.

You'll probably also have to time out IDs in the Map so you don't leak memory if no response arrives from a given request (for whatever reason).