简体   繁体   中英

How to implement Request – response logic using socket

HTTP HttpRequest(json) .then(result=> console.log(result)) .catch(error => console.error(error))

But, if you use socket

socket.send (json) - in one place code

socket.on (message) - elsewhere in the code

I want to do so: socketRequest(json) .then(result=> console.log(result)) .catch(error => console.error(error))

It's all about programming the socketRequest module)

It's all about your protocol design.

Sockets are designed to emulate how serial interfaces work - data come in 8 bits at a time and... nothing else. Sockets have no concept of messages - just bytes. Think of sockets as a USB keyboard. Your software only get bytes as users type one letter at a time (sometimes your software get groups of bytes if the user types fast enough or keep pressing a key). You need to decide what makes a "packet". A sentence? Then your software should detect full stops "." . A line? Then you detect newlines.

The following is a simple example of an HTTP 1.0 client (the main difference is that HTTP 1.0 signals end of packet by closing the connection while HTTP 1.1 sends a Content-Length header):

function HTTP_1_0_client (url) {
    let urlParts = url.match(/http:..([^/]+)(.*)/);
    let domain = urlParts[1];
    let path = urlParts[2];

    return new Promise((resolve, reject) => {
        let rawString = '';

        const client = net.createConnection(80, domain);
        client.write('GET ' + path + ' HTTP/1.0\n\n');
        client.on('data', buf => rawString += buf.toString());
        client.on('end', () => {
            // headers and body are separated by two newlines:
            let httpParts = rawString.match(/^(.+)\r?\n\r?\n(.*)/);
            let headers = httpParts[1].split(/\r?\n/);
            let text = httpParts[2];

            // first line of response is the status line:
            let statusLine = headers.shift();
            let status = statusLine.match(/^[0-9]+/)[0];

            // return the response to the promise:
            resolve({
                status: status,
                headers: headers,
                responseText: text
            });
        });
        client.on('error', err => reject(err));
    });
}

In the protocol above we simply use socket connection as the end of packet - thus end of response. You can use other conditions to detect the end of the response cycle and return the response. It all depends on the protocol design.

The following is another simple protocol that simply uses the JSON format to define a packet:

function JSONclient (host, port, requestData) {
    return new Promise((resolve, reject) => {
        let rawString = '';

        const client = net.createConnection(port, host);
        client.write(JSON.stringify(requestData));
        client.on('data', buf => {
            rawString += buf.toString();

            try {
                let response = JSON.parse(rawString);

                // If we get here it means no errors
                // which means packet is complete -
                // return response to promise:
                resolve(response);

                client.destroy(); // close connection
            }
            catch (err) {
                // Ignore parse error
                // It just means packet isn't complete yet.
            }
        });
        client.on('error', err => reject(err));
    });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM