爱意满满的作品展示区。
xiejay97

用 Node.js 写了个工业级 Modbus 协议栈,想听听大家的看法

  •  
  •   xiejay97 ·
    xiejay97 · Jun 27 · 1965 views

    最近把一个压箱底的项目开源了:njs-modbus,一个零依赖、strict TypeScript 的 Node.js Modbus 协议栈,支持 TCP / RTU / ASCII / UDP / TLS 。

    先上链接:


    为什么又要造轮子?

    在 IIoT 边缘干了十多年,被各种 Modbus 库坑惨了:

    • GC 一抖,100 ms 轮询变 300 ms ,PLC 直接报警;
    • 帧边界全靠"睡一会儿再读",产线 EMI 一来就粘包断包;
    • 每个请求 new 对象,几千点并发时 Node.js GC 过山车;
    • 安全策略等于"端口不外开",真放 DMZ 里连白名单都没有。

    大多数 Node.js Modbus 库没把自己当成工业软件写。所以我们决定自己写一个:运行时零依赖、strict TypeScript ,从第一行代码就按产线标准来。


    几个我们觉得不一样的地方

    1. 热路径真的在抠微秒

    • TCP 编解码约 0.11 µs,RTU 约 0.12 µs,ASCII 约 0.13 µs
    • 解码路径 gc_ns_per_op = 0,不分配对象;
    • Queue 用七个平行原始类型数组 + head index ,拒绝 Array.shift()

    不是炫技,是现场 P99 真的会被这些小地方吃掉。

    2. 韧性不是边缘补丁

    我们做了混沌测试:截断帧、粘包、垃圾字节、CRC 篡改、超长帧。结果是 TCP/RTU/ASCII 全过,而同类库在 RTU 上只有 8/12 和 3/12 。

    更具体一点:噪声过去后,TCP 模式下约 270 µs、RTU 模式下约 850 µs 就能重新锁定下一帧头部,不销毁连接、不重启实例。

    3. Transport-agnostic 是真的

    Pipeline 层就一个薄接口:

    interface AbstractPipelineAdapter {
      write(data: Buffer, cb?: (err?: Error) => void): void
      on(event: 'data', listener: (data: Buffer) => void): this
    }
    

    TCP 、TLS 、UDP 、Serial 、WebSocket 、你自己的硬件抽象,都能接。示例里 WebSocket Pipeline 只写了 133 行。

    4. 安全不是"端口不外开"

    • 三关鉴权:unit 、address 、runtime ;
    • 连接级:IP 白名单(精确/CIDR/自定义 predicate )、maxConnections 、maxConnectionsPerIp 、idleTimeout ;
    • 原生 TLS ,含 mutual TLS ;
    • 所有拒绝都生成结构化 audit log ,可直接打 SIEM 。

    想聊的

    1. 大家在工业现场用 Node.js 做 Modbus 主站/从站,最怕遇到什么问题?
    2. 你们觉得一个协议栈要做到什么程度,才敢写进给客户的技术方案?
    3. 严格 TS + 零依赖这条路线,在你们的项目里吃得开吗?

    欢迎拍砖,Issue 和 PR 都开放。

    15 replies    2026-06-29 11:19:30 +08:00
    sir283
        1
    sir283  
       Jun 27   ❤️ 2
    你这个相对于传统 QT 和 C#的 modbus ,有什么优势吗?如果客户机器的配置比较低呢?比如单核+128MB 内存+4GB 存储这种配置规格,完了还时不时拉总闸断电,然后重启,那你的库还能长期稳定可靠吗?我之前在深圳富士康做过上位机,我用的是 Qt C++的 Modbus TCP ,Qt 写的界面,一直很稳定,现在都运行两年了,而且程序内存占用稳定 50MB 左右,峰值不到 100MB ,你的库能做到吗?
    yplam
        2
    yplam  
       Jun 27
    1. 压测用 115200 波特率也体现不了性能,瓶颈在串口传输;
    2. TCP 本身就抗 EMI ,不会出现垃圾字节,除非实现有问题;
    3. RTU 协议你是否遵循静默时间来分帧? 1ms 超时时间 Nodejs 如何实现?
    keenkiller
        3
    keenkiller  
       Jun 27 via Android
    你写的痛点简直莫名其妙,边缘端你为啥不直接用 C 语言,如果说之前是门槛太高,现在用 AI 还有啥门槛
    terranboy
        4
    terranboy  
       Jun 27
    现在 Modbus 早不是主流了吧
    iamocean
        5
    iamocean  
       Jun 27
    你把 nodeJS 内存起码得 200M 以上吧?
    zsxzy
        6
    zsxzy  
       Jun 27
    好久没搞嵌入式.. 以前写这种协议层的东西,基本就 c/c++ , 保证实时可控为啥要用 ts ..
    shiny
        7
    shiny  
    PRO
       Jun 27
    “不是炫技,是现场 P99 真的会被这些小地方吃掉。”这个句式看着像是 GPT 写的
    xiejay97
        8
    xiejay97  
    OP
       Jun 27 via Android
    @sir283 快速开发,而且 nodejs 单线程天然适合 io 程序。云边缘还是很多用 nodejs 的。关于内存,这个压力在软件实现框架,不是协议本身,当前库实现压测不存在内存泄露。
    xiejay97
        9
    xiejay97  
    OP
       Jun 27 via Android
    @yplam 1. 体现不了性能但是该优化一样做。而且真正的价值在于抗干扰,不丢帧。
    2. 这个是安全合规要求,要考虑 master 端攻击处理。
    3. 3.5t 和 1.5t 都实现,时间戳加安全定时器能保证 1ms 准确判断。
    xiejay97
        10
    xiejay97  
    OP
       Jun 27 via Android
    @shiny 哥们,现在技术人写长点的东西都会借助 ai 吧,只要能表达出来自己想要的,而且不要像个人机(尊重读者)
    macheng
        11
    macheng  
       Jun 28 via iPhone
    都工业级了还 nodejs 吗
    cccn
        12
    cccn  
       Jun 28
    @macheng 正是我想问的。
    xiejay97
        13
    xiejay97  
    OP
       Jun 28
    @macheng 1.rust 也有包。2. 语言只是实现目的的工具,工业级从来不是用某个语言来判定,而是设计想法(因为这个是被任何语言实现的东西,协议本身就是这种东西)。
    sq955
        14
    sq955  
       Jun 29
    @macheng #11 我们 C# nodejs 都用,没啥问题
    xivcm
        15
    xivcm  
       Jun 29
    nodejs 非常适合做 demo 验证一下想法 从浏览器到服务端到 mcu 都方便迁移。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1202 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 54ms · UTC 17:41 · PVG 01:41 · LAX 10:41 · JFK 13:41
    ♥ Do have faith in what you're doing.