Node.js RPC 介绍和半双工简单代码实现(新手版)

什么是 RPC

本篇是极客时间杨浩老师的概括总结。首先点开这篇文章的你肯定会疑惑,什么是RPC呢?既然有了HTTP协议为什么还需要RPC?

RPC 与 HTTP 作比较

  1. RPC本质上不算是协议,而是一种调用方式
  2. RPC的实现是基于Socket之上的
  3. HTTP是90年代才开始流行的,在TCP之上之前有很多替代的协议,这就包括RPC,也就说在没有HTTP协议的时代,很多人用RPC发送数据的。

那为什么现在有了 HTTP 我们还需要学习 RPC 呢?

有一个比较直观的理解就是在 c/s 架构下 (client/server), RPC 可以使用在公司内网,进行数据传输。

RPC 的技术不同点

  1. 不一定使用DNS作为寻址服务(在内网里互相请求)
  1. RPC应用层协议通常不使用HTTP,而是采用基于二进制的协议来替代HTTP

RPC传输二进制协议,相比HTTP

  1. 更小的数据包体积

  2. 更快的编解码速率

  1. 基于TCP或UDP协议

RPC 技术实现

二进制传输实现

使用 Node.js 中的 Buffer API 详情见官网文档Buffer | Node.js v18.17.1 Documentation (nodejs.org)

这里需要掌握两个创建 Buffer 的语法,用于二进制传输

  1. Buffer.from
  • 可以接受多种输入类型作为参数,包括字符串、数组、Buffer对象
  • 提供的数据可以直接填充到Buffer中,const bufferFromStr = Buffer.from('Hello');
  • 如果提供了字符串,则可以指定编码格式,例如'utf8'、'hex'等,默认为'utf8'。
  1. Buffer.alloc
  • 创建指定大小的新的Buffer对象,并将所有字节设置为零(初始化)。
  • 接受一个整数参数,表示要分配的字节数。

RPC 半双工代码

server 端

js 复制代码
const net = require('net')

const server = net.createServer((socket) => {
    socket.on('data', function (buffer) {
        const fruitId = buffer.readInt32BE()
        const fruitData = data[fruitId];
        if(fruitData !== undefined) {
            const bufferc = Buffer.from(fruitData);
            setTimeout(() => {
                socket.write(bufferc);
            }, 500);
        } else {
            console.log("fruitId: " + fruitId + " doesn't exist.")
        }
        
        console.log(buffer, buffer.toString())
    })
})

const data = {
    136797: "01 草莓",
    136798:"02 香蕉",
    136799: "03 西瓜",
    136808: "04 榴莲",
    136801: "05 菠萝蜜",
    136803: "06 香瓜",
    136804: "07 白兰瓜",
}

server.listen(4000)

client 端

js 复制代码
const net = require('net')

const socket = new net.Socket({})

socket.connect({
    host: '127.0.0.1',
    port: 4000
})

const id = [
    "136797",
    "136798",
    "136799",
    "136808",
    "136801",
    "136803",
    "136804",
]

// 请求第一次发送
let index = Math.floor(Math.random() * id.length)
socket.write(encode(index))

socket.on('data', (buffer) => {
    const fruitBuffer = buffer;
    console.log(fruitBuffer.toString())

    index = Math.floor(Math.random() * id.length)
    socket.write(encode(index))
})

function encode(index) {
    let buffer = Buffer.alloc(4)
    buffer.writeInt32BE(
        id[index]
    )
    console.log(id[index])
    return buffer
}
相关推荐
追逐时光者2 小时前
精选 4 款基于 .NET 开源、功能强大的 Windows 系统优化工具
后端·.net
TF男孩2 小时前
ARQ:一款低成本的消息队列,实现每秒万级吞吐
后端·python·消息队列
excel2 小时前
ES6 中函数的双重调用方式:fn() 与 fn\...``
前端
可乐爱宅着3 小时前
全栈框架next.js入手指南
前端·next.js
AAA修煤气灶刘哥3 小时前
别让Redis「歪脖子」!一次搞定数据倾斜与请求倾斜的捉妖记
redis·分布式·后端
AAA修煤气灶刘哥4 小时前
后端人速藏!数据库PD建模避坑指南
数据库·后端·mysql
你的人类朋友4 小时前
什么是API签名?
前端·后端·安全
昵称为空C6 小时前
SpringBoot3 http接口调用新方式RestClient + @HttpExchange像使用Feign一样调用
spring boot·后端
会豪6 小时前
Electron-Vite (一)快速构建桌面应用
前端
中微子6 小时前
React 执行阶段与渲染机制详解(基于 React 18+ 官方文档)
前端