背景介绍
DAB(Device Automation Bus)是一种基于 MQTT 通信的轻量级协议,主要用于连接客厅中的消费电子产品(如智能电视和游戏机),并实现自动化测试。由于设备认证需要支持 DAB 功能,我们面临了开发 DAB 软件的紧迫任务。时间紧、任务重,挑战巨大。
第一阶段:学习与调研
1. 学习 DAB 协议
在项目初期,我深入学习了 DAB 协议,并将其整理成文档与团队分享。通过快速学习,我对 DAB 的整体架构和功能有了全面的理解,并整理出了 28 个核心接口。在此过程中,我发现了第一版协议中缺少对通信设备的标识。第二版协议中,增加了设备标识功能。
2. 调研设备现状
根据 DAB 协议,我对当前设备的基本情况进行了详细调研,重点分析了以下问题:
- 实现 DAB 需要哪些组件和功能?
- 现有设备中是否有可复用的组件或功能?
- 如何最大化复用现有资源?
通过调研,我明确了设备现状,并制定了两种实现方案。
第二阶段:方案设计与技术选型
1. 两套实现方案
我设计了两套 DAB 实现方案:
- 方案一:在电视外部部署 MQTT 服务。
- 方案二 :复用电视内部的 MQTT 服务。
经过评估,方案二在认证场景中更具优势,因为它减少了外部依赖,简化了部署流程。然而,复用设备内部的 MQTT 服务也带来了潜在的安全风险。为此,我们采取了以下安全措施:
- 云端授权机制。
- 超时自动关闭功能。
2. 开发语言选择
在开发语言的选择上,我们综合考虑了以下因素:
- DAB 开源 Demo 的语言支持。
- 认证设备的语言兼容性。
尽管团队更熟悉 C++,但为了缩短开发周期并赶上设备认证时间点,我们最终选择了 Node.js。此外,我们将 DAB 服务集成到现有进程中,减少了服务数量并复用了设备功能。
第三阶段:Node.js 版本的开发与挑战
1. 开发过程
使用 Node.js 开发 DAB 的过程中,我们充分利用了其单元测试功能,显著提升了开发效率和质量。然而,我们也遇到了一些挑战:
- 内存泄漏问题:由于进程内存增加导致异常,通过调整参数解决了这一问题。
- 接口与设备功能的适配:DAB 接口需要与多个设备功能模块对接,涉及多个项目组的协作,沟通成本较高。
2. Node.js 版本的局限性
尽管 Node.js 版本成功支撑了多个设备的 DAB 认证,但仍存在以下问题:
- 1.部分设备不支持 Node.js。
- 2.安全相关处理与业务逻辑分布在不同的进程中,由不同部门负责,协调成本较高。
第四阶段:C++ 版本的重构与优化
1. 开发背景
为了解决 Node.js 版本的局限性,我们开发了第二版 DAB,采用 C++ 实现。这一版本不仅避免了部分设备不支持 Node.js 的问题,还将安全处理逻辑集成到 DAB 内部,减少了跨部门沟通的复杂性。
2. 多平台支持与灵活性
在第二版设计中,我们特别注重灵活性和多平台支持:
- 支持在 Windows、公司开发平台以及设备上运行。
- 既可以独立运行,也可以嵌入到其他进程中。
为了实现这一目标,我添加了一个适配层,用于屏蔽不同平台的差异。适配层提供了多种实现策略,根据运行场景动态选择,从而加快了开发和调试速度。
第五阶段:开发中的经验与反思
1. 项目管理与沟通
由于时间紧迫,我采取了以下措施确保项目顺利推进:
- 提前与参与者沟通,明确目标、时间要求和注意事项。
- 使用 Jira 工具进行任务分解和进度跟踪。
- 在开发过程中及时纠偏,确保项目按计划进行。
2. 技术设计与优化
在技术实现上,我遵循了正交性原则,尽量减少模块之间的耦合。例如:
- 使用函数对象代替接口,使每个模块独立且无依赖。
- 为每个模块编写单元测试,提升开发质量和速度。
然而,在适配层设计中,我一度犯了过度设计的错误,尝试将 Netflix 的 C 语言面向对象实现引入项目中。经过反思,我及时调整了设计,简化了代码结构。
调整前的代码:
-- javascript typescript shell bash sql json html css c cpp java ruby python go rust markdown
#include <string>
#include <vector>
#include "dab/dab_api.h"
extern "C" {
struct DAB_API_IO {
DAB_Interface iface;
bool (*getKeyList)(std::vector<std::string>& list);
bool (*pressKey)(const char* key, int durationMs);
bool (*catpureImage2png)(const char* file);
};
const DAB_API_IO& getDABAPIIO();
}
调整后的代码:
-- javascript typescript shell bash sql json html css c cpp java ruby python go rust markdown
#pragma once
#include <string>
#include <vector>
extern "C" {
bool dab_api_getKeyList(std::vector<std::string>& list);
bool dab_api_pressKey(const char* key, int durationMs);
bool dab_api_catpureImage2png(const char* file);
}
第二版的亮点与遗憾
亮点
单元测试:摆脱环境依赖,在开发云平台、设备等环境中快速执行测试,提高开发效率。
2. 2.
灵活的部署:支持在 Windows、开发云平台和设备上单独运行,也可以嵌入到其他进程中运行,极大提升了灵活性。
3. 3.
适配层:隔离变化,使代码逻辑快速稳定。
4. 4.
灵活的接入策略:为各平台切换提供便利,即使在依赖项不具备的情况下也能顺利开展工作。
5. 5.
与实践结合:提出了许多对测试有用的应用场景和扩展。
6. 6.
高效的开发速度:通过合适的模式和策略,极大加快了开发速度。
7. 7.
文档生成代码:实践了由文档生成代码的方式,加快了开发速度并保证了准确性。
遗憾
嵌入进程的部署方式:增加了对安全性的依赖,特别是对安全性的要求更高。
2. 2.
与实践结合的时机:最初主要围绕认证需求开发,未能更早与实践和用户结合,导致成熟速度较慢。
总结
通过 DAB 的开发,我深刻体会到在紧迫时间内完成复杂项目的挑战与成就感。从协议学习到多平台实现,我们不仅解决了技术难题,还优化了团队协作和项目管理流程。
DAB标准:https://github.com/device-automation-bus/dab-specification-2.0
关键词:DAB、MQTT、Node.js、C++、多平台支持、正交性原则、单元测试、项目管理