HarmonyOS APP开发---“云诊室“在线问诊App,需要用到这个库

HarmonyOS APP开发---"云诊室"在线问诊App,需要用到这个库> 医患问诊要持续互发消息,患者还要每秒上传心率血压。用 REST 轮询,一秒一次请求既费电又延迟高;用 WebSocket,处方字段拼错了要到运行时才发现。@ohos/grpc 的双向流 + Protobuf 契约,正好对上医疗场景对实时性和准确性的双重要求。> 📦 仓库地址 | ohpm install @ohos/grpc---## 场景"云诊室"的通信需求:- 患者发症状描述、检验报告图片- 医生实时回诊断意见、开处方- 患者端手环持续上传心率/血压- 一次问诊可能持续十几分钟,连接要一直保持四个特点:双向 (双方都主动发)、持续 (长连接)、多类型 (文字+图片+结构化数据混在一个会话)、不能错 (处方剂量字段拼错是医疗事故)。---## 为什么是 gRPC| 需求 | REST 轮询 | WebSocket | gRPC ||------|-----------|-----------|------|| 双向实时 | ❌ | ✅ | ✅ || 强类型契约 | ❌ JSON 无约束 | ❌ 手写协议 | ✅ Protobuf || 多路复用 | ❌ | ⚠️ 单流 | ✅ HTTP/2 || 二进制传输 | ❌ | ⚠️ | ✅ 高效 || 跨语言服务端 | ✅ | ✅ | ✅ Go/Java/Python |医疗场景的决定性因素是 Protobuf 契约 。处方字段、剂量单位、检验项编码,容不得"运行时才发现对不上"。.proto 文件是前后端唯一真相来源,改字段两端编译期就报错。---## 关键实现### 先用 .proto 定死契约protobufservice Consultation { rpc Chat(stream ChatMessage) returns (stream ChatMessage); // 双向流 rpc MonitorVitals(stream Vitals) returns (VitalsAck); // 客户端流}message ChatMessage { string session_id = 1; string from_role = 2; // patient / doctor MessageType type = 3; string text = 4; bytes attachment = 5; // 检验报告图片 int64 timestamp = 6;}enum MessageType { TEXT = 0; SYMPTOM = 1; DIAGNOSIS = 2; PRESCRIPTION = 3; }### 双向流问诊会话typescriptimport { grpc } from '@ohos/grpc'this.client = new grpc.Client('https://grpc.clinic.com', { credentials: grpc.credentials.createInsecure(),})this.chatStream = this.client.makeBidiStreamRequest( '/clinic.Consultation/Chat', (req) => req.serializeBinary(), (buf) => ChatMessage.deserializeBinary(buf), new grpc.Metadata({ 'x-session-id': this.sessionId }),)// 收医生消息this.chatStream.on('data', (msg: ChatMessage) => { this.messages.push({ from: msg.getFromRole(), text: msg.getText() }) if (msg.getType() === MessageType.PRESCRIPTION) this.showPrescription(msg)})this.chatStream.on('end', () => promptAction.showToast({ message: '医生已结束问诊' }))this.chatStream.on('error', (err) => this.reconnect())// 发症状this.chatStream.write(ChatMessage.encode({ sessionId: this.sessionId, fromRole: 'patient', type: MessageType.SYMPTOM, text: '最近三天头晕', timestamp: Date.now(),}).finish())一个连接里双方持续互发,不用为每条消息重新建连。医生的 typing 状态、已读回执、消息、附件全走同一个流。### 体征数据持续上传typescript// 患者端:客户端流const stream = this.client.makeClientStreamRequest( '/clinic.Consultation/MonitorVitals', ser, deser, (err, ack) => err ? console.error(err) : console.info(`已收 ${ack.getReceivedCount()} 条`),)this.timer = setInterval(() => { const v = readFromWearable() stream.write(Vitals.encode({ patientId: this.patientId, heartRate: v.heartRate, systolic: v.systolic, diastolic: v.diastolic, timestamp: Date.now(), }).finish())}, 1000)---## 两个容易踩的点1. 并发会话要限流 医生同时接诊多个患者时,无限开流会耗尽连接和内存。并发是 gRPC 最容易出问题的地方,业务侧要自己设上限:typescriptclass ConsultationManager { private sessions: Map<string, any> = new Map() private readonly MAX = 3 start(patientId: string): boolean { if (this.sessions.size >= this.MAX) { promptAction.showToast({ message: `最多同时接诊 ${this.MAX} 位患者` }) return false } const stream = this.createStream(patientId) this.sessions.set(patientId, stream) // ✅ 正常结束和异常都要清理,避免僵尸会话累积 stream.on('end', () => this.sessions.delete(patientId)) stream.on('error', () => this.sessions.delete(patientId)) return true } end(patientId: string) { this.sessions.get(patientId)?.end() // ✅ 优雅关闭,别直接丢引用 this.sessions.delete(patientId) }}2. 连接监控与指数退避重连 问诊中断是业务事故:typescriptprivate async reconnect() { for (let i = 1; i <= 5; i++) { await sleep(1000 * Math.pow(2, i - 1)) // 1s, 2s, 4s, 8s, 16s try { this.client = new grpc.Client(SERVER_URL, this.credentials) await this.healthCheck() this.sessionManager.restoreAll() // 重连后恢复所有会话 return } catch (e) { console.warn(`第 ${i} 次重连失败`) } } promptAction.showToast({ message: '网络异常,请检查网络' })}---## 小结"云诊室"这个场景里,@ohos/grpc 解决了三件事:双向流承载医患持续互发、客户端流承载体征数据上传、Protobuf 契约让医疗字段在编译期就有保障。上线前记得跑一遍仓库提供的并发压测 Demo------多会话并发是这类应用最容易出问题的地方。

相关推荐
0+11110 小时前
Linux --从 poll 到 epoll多路转接
linux·服务器·1024程序员节
阿狸猿10 小时前
论零信任安全架构在信息系统中的应用
1024程序员节
念何架构之路11 小时前
Go reflect 场景实战
1024程序员节
知已难寻11 小时前
第 2 篇 · 云的地基:服务器、存储、网络三大基础设施
运维·服务器·网络·云原生·云计算·负载均衡·1024程序员节
初阳78511 小时前
【基于Qt5仿音乐播放器(六)】——细节打磨与总结
qt·1024程序员节
信誓旦旦的程序猿13 小时前
【Python量化实战宝典 #26】止损与回撤控制手册:移动止损、最大回撤(Python 可跑)
python·1024程序员节·股票数据api·股票数据api接口·股票api数据接口·股票量化数据api·股票量化数据接口
鸿蒙开发14 小时前
共享 Schema 与 SchemaFactory
前端·后端·harmonyos
长不大的杨瑞杰16 小时前
OpenCode v2 MCP 与插件体系实战:把数据库、工单和内部 API 安全接入 Agent
人工智能·安全·语言模型·软件工程·1024程序员节
二流小码农16 小时前
HarmonyOS开发助手,0代码让元服务从开发到上架
android·ios·harmonyos