Search code examples
javascripthttptcp

Make HTTP requests without opening a new connection


If a browser opens a connection to a remote server, is it possible to access that same connection via Javascript?

I have a small Ethernet module on my network that I program sort of like this (pseudocode):

private var socket
while(true) {
    if(socket is disconnected) {
        open socket
        listen on socket (port 80)
    }
    if(connection interrupt) {
        connect socket
    }
    if(data receive interrupt) {
        serve
    }
    if(disconnection interrupt) {
        disconnect socket
    }
}

The point is that it listens on one socket for HTTP requests and serves them.

In my web browser, I can connect to the device, making an HTTP GET request for some HTML/JS that I've written, and it works. A connection is opened on the socket and the files come back as HTTP responses.

Now I want to click a button on the webpage and have the browser send an HTTP POST request over that same connection. In my Javascript, I have (edited and formatted for clarity):

// This function sends an HTTP request
function http(type, url, data, callbacks) {
    // make a new HTTP request
    var request = new XMLHttpRequest();

    // open a connection to the URL
    request.open(type, url + (data ? "?" + data : ""));

    // add headers
    if(type == "POST")
        request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

    // register callbacks for the request
    Object.keys(callbacks).forEach(function(callback) {
        request[callback] = function() {
            callbacks[callback](request.responseText);
        };
    });

    // send and return the request
    request.send();
    return request;
}

// Here is where I call the function
http("POST",                // use POST method
     "http://192.168.1.99", // IP address of the network device
     dataToSend,            // the data that needs to be sent
     {                      // callbacks
         onloadend: function(data) {
             console.log("success. got: " + data); // print 'success' when the request is done
         },
         onerror: function(data) {
             console.log("There was an error.");   // print 'error' when it fails
             console.log(data);
         }
     }
);

The issue here is that this opens a new connection to the device, but I want to use the same socket that the browser is already connected to. Is this possible, and if so, how?


Solution

  • There is no application control inside the browser to decide if a new connection is used for the next request or if an existing connection is used. In fact, it is perfectly normal that the browser will use multiple connections in parallel to the same server and your server has to be able to deal with this.

    Since your server architecture seems to be only able to deal with one connection at a time you either would need to change the architecture to handle multiple parallel connections or to make sure that you only need to handle a single connection at a time. The latter could be achieved by not supporting HTTP keep-alive, i.e. by closing the connection immediately after each response. This way a new request will result in a new connection (which is not what you wanted according to your question) but your server will also be able to handle this new connection (which is what you likely ultimately need) since the previous one was closed.