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
}
相关推荐
也无晴也无风雨29 分钟前
深入剖析输入URL按下回车,浏览器做了什么
前端·后端·计算机网络
Martin -Tang1 小时前
Vue 3 中,ref 和 reactive的区别
前端·javascript·vue.js
FakeOccupational3 小时前
nodejs 020: React语法规则 props和state
前端·javascript·react.js
放逐者-保持本心,方可放逐3 小时前
react 组件应用
开发语言·前端·javascript·react.js·前端框架
曹天骄4 小时前
next中服务端组件共享接口数据
前端·javascript·react.js
2401_857610034 小时前
多维视角下的知识管理:Spring Boot应用
java·spring boot·后端
阮少年、4 小时前
java后台生成模拟聊天截图并返回给前端
java·开发语言·前端
代码小鑫4 小时前
A027-基于Spring Boot的农事管理系统
java·开发语言·数据库·spring boot·后端·毕业设计
颜淡慕潇5 小时前
【K8S问题系列 | 9】如何监控集群CPU使用率并设置告警?
后端·云原生·容器·kubernetes·问题解决
郝晨妤5 小时前
鸿蒙ArkTS和TS有什么区别?
前端·javascript·typescript·鸿蒙