HarmonyOS APP开发—"股动力"实时行情App,需要用到这个库

想做一个股票行情 App,K 线、分时、盘口数据要实时推送?REST 轮询延迟高又费流量,WebSocket 又缺强类型契约——@ohos/grpc 的双向流式 RPC 才是正解。

📦 仓库地址:https://gitcode.com/CPF-ApplicationTPC/ohos_grpc_node | 安装:ohpm install @ohos/grpc


写在前面

“股动力"的核心难点是"实时性”。股票行情每秒可能产生几十条 tick,用户打开个股详情页,期望看到的是毫秒级刷新的分时线和盘口。

传统方案的问题:

  • REST 轮询:每秒请求一次,延迟最高 1 秒,流量浪费严重
  • WebSocket:能推送,但没有强类型契约,前后端字段对不上全靠口口相传
  • HTTP/1.1 长连接:单连接不能多路复用,并发请求互相阻塞

gRPC 基于 HTTP/2,天然支持流式通信 + Protobuf 强类型。服务端持续推 tick,客户端持续发订阅,单连接多路复用——这就是"股动力"选它的原因。

这篇文章聊什么

  1. Unary RPC——拉取股票基本信息(一次性请求)
  2. Server Streaming——服务端持续推送实时 tick
  3. 双向流——客户端发订阅,服务端推行情

打开个股页

Unary: 拉基本信息

Server Stream: 订阅 tick

服务端持续推送

渲染 K 线/分时

切换股票?

Bidi: 发新订阅


第一步:安装

ohpm install @ohos/grpc

安装后需将仓库 protobufjs/index.d.ts 替换到 oh_modules 对应路径,确保 Protobuf 类型完整。


第二步:Unary RPC——拉取股票基本信息

打开个股页,先拉一次静态信息(名称、昨收、总股本等):

import { grpc } from '@ohos/grpc'

const client = new grpc.Client('https://grpc.market-server.com', {
  credentials: grpc.credentials.createInsecure()
})

// Unary:一次请求,一次响应
client.makeUnaryRequest(
  '/stock.StockService/GetInfo',
  (req) => req.serializeBinary(),
  (buf) => StockInfo.deserializeBinary(buf),
  StockRequest.encode({ code: '600519' }).finish(),
  (err, response) => {
    if (err) { console.error(err); return }
    console.info(`${response.getName()} 昨收 ${response.getPreClose()}`)
    // 渲染基本信息
  }
)

Unary 模式和普通 HTTP 请求很像——一问一答。适合拉取不频繁变更的静态数据。


第三步:Server Streaming——持续接收实时 tick

订阅某只股票后,服务端持续推送 tick 数据:

// Server Streaming:一次请求,持续接收
const stream = client.makeServerStreamRequest(
  '/stock.StockService/SubscribeTick',
  (req) => req.serializeBinary(),
  (buf) => Tick.deserializeBinary(buf),
  SubscribeRequest.encode({ code: '600519', level: 1 }).finish()
)

stream.on('data', (tick) => {
  // 每收到一个 tick,更新 K 线和盘口
  console.info(`价格 ${tick.getPrice()}${tick.getVolume()}`)
  updateChart(tick)
})

stream.on('end', () => {
  console.info('行情推送结束(收盘)')
})

stream.on('error', (err) => {
  console.error('行情异常: ' + err)
})

这就是 gRPC 流式的核心优势——一个请求建立流,服务端持续推,无需反复建连。比 REST 轮询省流量、低延迟,比 WebSocket 多了 Protobuf 强类型。


第四步:双向流——动态切换订阅

用户从 A 股切到 B 股,不需要断开重连,直接在同一个流里发新订阅:

const bidiStream = client.makeBidiStreamRequest(
  '/stock.StockService/WatchMulti',
  serializer,
  deserializer,
  metadata
)

// 收到行情
bidiStream.on('data', (tick) => {
  updateChart(tick)
})

// 动态发订阅:先订阅 A,再切到 B
bidiStream.write(Subscribe.encode({ code: '600519' }).finish())

// 用户切换股票
setTimeout(() => {
  bidiStream.write(Subscribe.encode({ code: '000858' }).finish())
}, 5000)

// 取消订阅
bidiStream.write(Unsubscribe.encode({ code: '600519' }).finish())

双向流是 gRPC 最强大的模式——一个连接管多只股票的订阅/取消,互不干扰。这在 REST 里要维护一堆连接状态,在 gRPC 里就是几行 write


为什么"股动力"选了 gRPC?

需求 REST 轮询 WebSocket gRPC
实时推送 ❌ 轮询延迟高 ✅ 可推送 ✅ 流式推送
强类型契约 ❌ JSON 无约束 ❌ 无 ✅ Protobuf
多路复用 ❌ 多连接 ⚠️ 单流 ✅ HTTP/2
动态订阅 ❌ 难管理 ⚠️ 手写协议 ✅ 双向流
跨语言 ✅ Go/Java/Python 互通

总结

"股动力"这个场景里,@ohos/grpc 解决了三件事:

  1. 静态信息——Unary RPC 一问一答,拉股票基本信息
  2. 实时行情——Server Streaming 持续推送 tick,毫秒级触达
  3. 动态订阅——双向流,切股票不断连,发个 write 就行

如果你也在做实时行情、在线协作、IoT 网关双向通信等场景,@ohos/grpc 的流式能力会让你彻底忘掉 REST 轮询的痛。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐