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
}
相关推荐
月光下的丝瓜11 分钟前
Flutter 国内安装指南
前端·flutter
用户83562907805123 分钟前
使用 Python 在 PDF 中创建与管理书签
后端·python
Nturmoils23 分钟前
字段太多看不全,ksql 的展开模式和输出控制怎么用
数据库·后端
大志说编程24 分钟前
Agent面试真题06: 十分钟带你快速掌握Agent记忆管理高频面试题(附详细答案)
后端·面试·ai编程
玄星啊27 分钟前
AI 编程的第 30 天,我怀念古法 Coding 了
前端·ai编程
Jolyne_27 分钟前
Angular基础速通
前端·angular.js
ServBay37 分钟前
Claude Code 被曝植入后门,AI 时代如何安全打造本地 DevOps
后端·ai编程·claude
王二端茶倒水1 小时前
从千兆到万兆:宽带运营不能只卖套餐,要管用户生命周期从千兆到万兆:宽带运营需要管理用户生命周期
后端·网络协议·架构
锋行天下1 小时前
半秒开!还有谁!!!
前端·vue.js·架构