教你用 Rust 实现 Smpp 协议
本文分享自华为云社区《华为云短信服务教你用Rust实现Smpp协议》,作者: 张俭。
协议概述
SMPP(Short Message Peer-to-Peer)协议起源于 90 年代,最初由 Aldiscon 公司开发,后来由 SMPP 开发者论坛维护和推广。SMPP 常用于在 SMSC(Short Message Service Center,短信中心)和短信应用之间传输短消息,支持高效的短信息发送、接收和查询功能,是电信运营商和短信服务提供商之间互通短信的主要协议之一。
SMPP 协议基于客户端/服务端模型工作。由客户端(短信应用,如手机,应用程序等)先和 SMSC 建立起 TCP 长连接,并使用 SMPP 命令与 SMSC 进行交互,实现短信的发送和接收。在 SMPP 协议中,无需同步等待响应就可以发送下一个指令,实现者可以根据自己的需要,实现同步、异步两种消息传输模式,满足不同场景下的性能要求。
时序图
绑定 transmitter 模式,发送短信并查询短信发送成功
绑定 receiver 模式,从 SMSC 接收到短信
协议帧介绍
在 SMPP 协议中,每个 PDU 都包含两个部分:SMPP Header 和 SMPP Body。
SMPP Header
Header 包含以下字段,大小长度都是 4 字节:
Command Length:整个 PDU 的长度,包括 Header 和 Body。
Command ID:用于标识 PDU 的类型(例如,BindReceiver、QuerySM 等)。
Command Status:响应状态码,表示处理的结果。
Sequence Number:序列号,用来匹配请求和响应。
用 Rust 实现 SMPP 协议栈里的 BindTransmitter
本文的代码均已上传到smpp-rust
选用 Tokio 作为基础的异步运行时环境,tokio 有非常强大的异步 IO 支持,也是 rust 库的事实标准。
代码结构组织如下:
lib.rs Rust 项目的入口点
const.rs 包含常量定义,如 commandId、状态码等
protocol.rs 包含 PDU 定义,编解码处理等
smpp_client.rs 实现 smpp 客户端逻辑
smpp_server.rs 实现
利用 rust 原子类实现 sequence_number
sequence_number 是从 1 到 0x7FFFFFFF 的值,利用 Rust 的 AtomicI32 来生成这个值。
在 Rust 中定义 SMPP PDU
实现编解码方法
实现同步的 bind_transmitter 方法
运行 example,验证连接成功
相关开源项目
netty-codec-sms 存放各种 SMS 协议(如 cmpp、sgip、smpp)的 netty 编解码器
sms-client-java 存放各种 SMS 协议的 Java 客户端
sms-server-java 存放各种 SMS 协议的 Java 服务端
smpp-rust smpp 协议的 rust 实现
总结
本文简单对 SMPP 协议进行了介绍,并尝试用 rust 实现协议栈,但实际商用发送短信往往更加复杂,面临诸如流控、运营商对接、传输层安全等问题,可以选择华为云消息 &短信(Message & SMS)服务,华为云短信服务是华为云携手全球多家优质运营商和渠道,为企业用户提供的通信服务。企业调用 API 或使用群发助手,即可使用验证码、通知短信服务。
版权声明: 本文为 InfoQ 作者【华为云开发者联盟】的原创文章。
原文链接:【http://xie.infoq.cn/article/0ad98aa92d5db6949a24be4b7】。文章转载请联系作者。
评论