How to create a multiplexed RPC channel with NET

The guide language

We have learned what RPC channels are, today we will try to use the Node NET module to implement RPC channels.

On the net

Net module and HTTP module are used similarly, see nodejs.org/dist/latest…

Create an RPC channel for simplex communication using NET

  1. First, create two JS files: client and server
  2. Add net module to the server file, and create a server using net module, and then listen for port 4000 (the port number can be custom, I listen for port 4000 here), code as follows:
    const net = require("net"); // Introduce the NET module

    / / create a server
    // socket: a proxy object written to and removed from the network channel
    let server = net.createServer((socket) = > {
      socket.on("data".(buffer) = > {
        // Listen for data events
        console.log(buffer, buffer.toString());
      });
    });

    server.listen(4000);
Copy the code
  1. Net module is also introduced in the client file, creating a Socket object, the Socket object is connected to the server, and then you can use the socket.write method to write the content that needs to be sent. The code is as follows:
    const net = require("net");

    let socket = new net.Socket({}); // Create a socket object

    // Connect to the server server
    socket.connect({
      host: "127.0.0.1".port: 4000}); socket.write("hello wlf"); / / send
Copy the code
  1. Start the client and server servers respectively, and the server can get the content sent by the client.

Net to create an RPC channel for half duplex communication

The characteristic of half duplex communication is that the next request can only be sent after the last request has returned the result! The client code is as follows:

    const net = require("net");

    let socket = new net.Socket({}); // Create a socket object

    // Connect to the server server
    socket.connect({
      host: "127.0.0.1".port: 4000}); socket.write(send(Math.floor(Math.random() * 8))); / / send

    socket.on("data".(buffer) = > {

      console.log(buffer.toString());

      // After each result, set a timer to continue sending messages after two seconds
      setTimeout(() = > {
        socket.write(send(Math.floor(Math.random() * 8))); / / send
      }, 2000);
    });

    // Encapsulate the code that sends the message as a method
    function send(id) {
      let buf = Buffer.alloc(2);
      buf.writeInt16BE(id, 0);
      return buf;
    }
Copy the code

Server side code:

const net = require("net"); // Introduce the NET module

/ / create a server
// socket: a proxy object written to and removed from the network channel
let server = net.createServer((socket) = > {
  socket.on("data".(buffer) = > {
    // Listen for data events
    let dataId = buffer.readInt16BE();
    console.log(dataId);
    socket.write(Buffer.from(data[dataId]));
  });
});

server.listen(4000);

/ / data
let data = {
  0: "Liu Zongyuan".1: "Han yu".2: "Ouyang Xiu".3: "Su Xun".4: "Su shi".5: "Su zhe".6: "Wang Anshi".7: "曾巩"};Copy the code

Result: A request is made and a result is received after each two seconds.

Duplex communication

Based on the characteristic of duplex communication, which is free to send and return messages, our code may encounter a problem: how to determine the correspondence between the sent message and the returned message? Let’s draw a picture to illustrate the problem:

As shown above: When the client sends two messages, msg1 and MSG2, at the same time, the server receives the two messages and starts processing them. The result of msG2 is returned first, and the result of MSG1 is returned later. How does the client match the received data to the sent data?

To solve this problem, we need to add the same identity ID to both the sent and returned data.

Client code:

    const net = require("net");

    let socket = new net.Socket({}); // Create a socket object

    // Connect to the server server
    socket.connect({
      host: "127.0.0.1".port: 4000});// Send a packet every 50ms
    setInterval(() = > {
      socket.write(send(Math.floor(Math.random() * 8))); / / send
    }, 50);

    socket.on("data".(buffer) = > {
      console.log(buffer.slice(0.2).readInt16BE(0), buffer.slice(2).toString());
    });

    // Encapsulate the code that sends the message as a method
    let flagId = 0; //标识ID
    function send(id) {
      let buf = Buffer.alloc(4);
      buf.writeInt16BE(flagId, 0); // Put the ID in the buffer header
      buf.writeInt16BE(id, 2);
      flagId++;
      return buf;
    }
Copy the code

Server side code:

const net = require("net"); // Introduce the NET module

/ / create a server
// socket: a proxy object written to and removed from the network channel
let server = net.createServer((socket) = > {
  socket.on("data".(buffer) = > {
    // Listen for data events
    let flagBuf = buffer.slice(0.2); // Fetch the ID
    let dataId = buffer.readInt16BE(2);/ / read id
    console.log(flagBuf.readInt16BE(0), dataId);
		// The timer is out of order
    setTimeout(() = > {
      socket.write(Buffer.concat([flagBuf, Buffer.from(data[dataId])])); // Use concat to concatenate the content and identity ID to be returned
    }, 1000 * Math.random() + 10);
  });
});

server.listen(4000);

/ / data
let data = {
  0: "Liu Zongyuan".1: "Han yu".2: "Ouyang Xiu".3: "Su Xun".4: "Su shi".5: "Su zhe".6: "Wang Anshi".7: "曾巩"};Copy the code

Client result:

Server result:

The comparison between client and server can determine whether the data returned by the order is correct.

conclusion

Today we learned how to use node’s NET module to create simple multiplexed RPC channels. By learning this section, I have a deeper understanding of RPC channels. Well, see you next time! Good good study, day day up!