什么是 SMPP?企业短信背后的那条长连接
不用术语讲 SMPP:绑定、窗口、PDU 与回执路径,以及为什么在高吞吐场景里连接形态本身很重要。
SMPP 是平台与短信中心之间交换短消息的协议,跑在一条持续打开的会话上。绑定声明方向,会话带着吞吐窗口,送达回执以 PDU 返回。它不是一问一答的 API。
要点
- SMPP 是一条持续打开的会话,绑定时声明方向。
- 一个绑定承载一份吞吐配额和一个在途请求窗口。
- 一条 PDU 有 16 字节头部,报文体随命令而变。
- 送达回执异步返回,按 message ID 匹配。
本页内容
是会话,不是一次调用
SMPP 在您的平台和短信中心之间保持一条连接。平台认证一次,声明要做什么,之后就在同一条会话上提交消息、接收事件。短信中心不必等新的请求才发回执或上行的短信。有结果要报时,它直接推一条 PDU 过来。
这种形态适合稳定的流量。会话状态已经建好,回执通道也一直开着,单条消息的开销就小。代价是客户端要自己管状态:绑定是否正常、在途窗口用了多少、心跳什么时候发、断线后怎么重连。这些在 HTTP 客户端里都不存在。
绑定声明方向
绑定就是通过认证的会话加一个方向。发送绑定(transmitter)用来提交消息,接收绑定(receiver)用来接收手机发起的消息和回执,收发绑定(transceiver)在一条会话里兼顾两者。服务商为每种绑定发凭据,也可能限制您能开几条。
扩容靠加绑定,不是把一条绑定推到配额之外。一条绑定对应一份吞吐配额和一个在途窗口。峰值不够,就再申请一条绑定,把流量摊开。一条绑定被推过窗口,换来的只会是限流、超时和重试。看起来像网络故障,根子在客户端。
绑定、提交、回执
- 应用(ESME)
- bind_transceiver 建立会话
- SMSC
- submit_sm_resp 已受理
- 送达回执
文字说明
应用打开绑定,短信中心返回响应。应用用 submit_sm 提交一条短信,收到带 message ID 的 submit_sm_resp。稍后短信中心发来 deliver_sm,里面是送达回执。应用用 deliver_sm_resp 确认。工作结束后发送 unbind,关闭会话。
窗口就是约定
窗口是客户端在等待响应之前可以同时在途的请求数。它不是建议值。发得比窗口多,短信中心就限流。限流后还按原速率重试,队列只会越积越长。每次提交都要读响应码,遇到限流就降速,等窗口排空再发下一波。
心跳用来确认会话还活着。从不发 enquire_link 的客户端,可能一直挂在一条已经死掉的连接上,直到第一次提交失败才发现。每次掉线都立刻重连的客户端,又会压垮服务商。要退避重连、限制重连频率,并在绑定中断超过业务可承受时间时告警。
一条 PDU,逐字段拆开
- command_length
- 53
- command_id
- 0x00000004
- command_status
- 0x00000000
- sequence_number
- 1
- service_type
- source_addr_ton
- 1
- source_addr_npi
- 1
- source_addr
- 12345
- dest_addr_ton
- 1
- dest_addr_npi
- 1
- destination_addr
- 15551234567
- esm_class
- 0x00
- protocol_id
- 0x00
- priority_flag
- 0
- schedule_delivery_time
- validity_period
- registered_delivery
- 0x01
- replace_if_present_flag
- 0x00
- data_coding
- 0x00
- sm_default_msg_id
- 0x00
- sm_length
- 4
- short_message
- 54657374
- 文本
- Test
文字说明
每条 PDU 都以四字节命令长度、四字节命令 ID、四字节命令状态和四字节序列号开头,后面是报文体。submit_sm 的报文体包括源地址、目的地址、短消息、数据编码和回执标志。可选参数以标签-长度-值字段传送。
一条短信的一天
客户端打开收发绑定,读取绑定响应。它提交一条短信,把响应里的 message ID 存下来。短信中心把短信路由到目的网络。几分钟后,一条 deliver_sm 带回回执:原始 message ID、状态,往往还有网络错误码。客户端确认回执,把状态和自己的记录对上。
每一步都有失败方式。凭据不对或接口版本不对,绑定会被拒。提交可能被限流、被拒绝,也可能先受理、后面在回执里失败。回执可能在验证码过期之后才到。客户端要存 message ID,能接受迟到的回执,并把应用自己的状态当作“用户做了什么”的准绳。
先解码回执,再怀疑路由
把一条送达回执粘进 SMPP 与 DLR 解码器,逐字段读。看 message ID、状态、完成时间和错误码。状态不是 DELIVRD 时,错误码要对照服务商的代码表来读,可据此判断是号码、手机还是网络拒绝了这条短信。先做这一步,再让服务商改路由。
回执与排障
回执是异步的,以 deliver_sm PDU 的形式回到会话上,格式取决于短信中心。较新的实现把状态放在 message_state 这个标签-长度-值字段里。较旧的实现把文本回执放进短消息字段,用 id、stat、err 这样的键值对表示。两种都要能解析,不能只认一种。
按 message ID 匹配,不要按到达顺序。相隔一秒提交的两条短信,回执可能倒着回来,重试还可能产生重复。提交时存下 ID,回执到达时更新记录。同一个 ID 的第二条回执只有状态更新时才采纳。接入指南把这套做法写成了一份操作顺序。
检查一下
-
为什么再加一条绑定,比提高重试速率更有用?
一条绑定只有一个窗口。加绑定是加容量,对着满窗口重试,只会增加排队和延迟。
-
message ID 从哪里来?
短信中心在 submit_sm_resp 里返回。存下它,之后按这个 ID 匹配回执。
-
“已送达”的回执能证明什么?
证明网络已接受并把短信送到手机方向,不证明有人读过。
答案按需展开。不评分、不存储、不外传。
常见问题
刚开始就必须用 SMPP 吗?
什么是绑定?
什么是 PDU?
可以走公网用 SMPP 吗?
长短信怎么处理?
相关内容
- 用 SMPP 和 HTTP 接入短信
把测试路由带到生产而不弄坏绑定、窗口和回执:绑定状态、吞吐、心跳、编码、回调与故障处理。
- RFQ 与 RFP 模板包
短信批发、eSIM 与数据、物联网与中国连接的字段清单,以及可在线作为 RFQ 发送的清单。
- 路由测试样例报告
脱敏的静态路由测试报告样例:路由测试检查什么、失败如何呈现,以及什么会触发路由复核。
相关产品
把结论用起来
告诉我们流量、目的地和需要的测量项,我们会回复下一步。