1)背景 併發
目前咱們的短信發送基本上就是超過140字節(甚至更少)就切分(移動普通短信超過140個字節甚至都發送不了,聯通卻是能夠),而後分幾條發給客戶,並且也不能保證順序,用戶體驗很差,tcp
運營這邊抱怨說精簡再精簡仍是超過了字數,因而長短信的支持就成爲必須的事情了。工具
2)原理測試
2.1)長短信的協議和普通短信的協議稍有不一樣io
2.1.1) TP_udhi=1 class
在Msg_content中加入6個字節或者7個字節的udhi頭作爲前綴原理
2.1.2)6個字節的TP_udhi協議頭 用戶體驗
05 00 03 XX MM NN互聯網
byte 1 : 05, 表示剩餘協議頭的長度終端
byte 2 : 00, 這個值在GSM 03.40規範9.2.3.24.1中規定,表示隨後的這批超長短信的標識位長度爲1(格式中的XX值)。
byte 3 : 03, 這個值表示剩下短信標識的長度
byte 4 : XX,這批短信的惟一標誌,事實上,SME(手機或者SP)把消息合併完以後,就從新記錄,因此這個標誌是否惟一併非很 重要。
byte 5 : MM, 這批短信的數量。若是一個超長短信總共5條,這裏的值就是5。
byte 6 : NN, 這批短信的數量。若是當前短信是這批短信中的第一條的值是1,第二條的值是2。
例如:05 00 03 39 02 01
2.1.3)7個字節的TP_udhi協議頭
06 08 04 XX XX MM NN
byte 1 : 06, 表示剩餘協議頭的長度
byte 2 : 08, 這個值在GSM 03.40規範9.2.3.24.1中規定,表示隨後的這批超長短信的標識位長度爲2(格式中的XX值)。
byte 3 : 04, 這個值表示剩下短信標識的長度
byte 4-5 : XX XX,這批短信的惟一標誌,事實上,SME(手機或者SP)把消息合併完以後,就從新記錄,因此這個標誌是否惟 一併非很重要。
byte 6 : MM, 這批短信的數量。若是一個超長短信總共5條,這裏的值就是5。
byte 7 : NN, 這批短信的數量。若是當前短信是這批短信中的第一條的值是1,第二條的值是2。
例如:06 08 04 00 39 02 01
2.2)實現方式
咱們的短信網關仍是要按140個字節切分短信,只是短信的字節和之前稍有不一樣(見2.1的說明),短信中心經過把切分的短信發送到手機終端,
手機終端根據udhi協議頭再把這幾條短信組合成一條完整的短信顯示在手機屏幕
3)action
3.0)簡略的下行流程
咱們的網關程序(SP)<-------CMPP2.0協議----->互聯網短信網關(ISMG)<-----SMPP協議--------->短消息中心(SMC)<-----無線協議---->手機終端
3.1)第一階段
條件:(6字節協議頭,TP_udhi=1, Pk_total Pk_number均爲1或者0或者和TP_udhi頭一致,Msg_Fmt爲Gbk)
終端沒法收到,從短信中心得到錯誤碼 MA:0054,意思是短信中心不返回行業網關響應消息
條件:(7字節協議頭,TP_udhi=1, Pk_total Pk_number均爲1或者0或者和TP_udhi頭一致,Msg_Fmt爲Gbk)
終端沒法收到,從短信中心得到錯誤碼MB : 1057,意思是短信中心返回行業網關錯誤響應消息
具體錯誤緣由,如何改正,我問過移動技術人員,沒有結果
3.2)第二階段
突發奇想,把Msg_Fmt改成ucs2,即設爲8而不是15,狀況發生了變化
條件:(6字節協議頭,TP_udhi=1, Pk_total Pk_number均爲1或者0或者和TP_udhi頭一致,Msg_Fmt爲ucs2)
能收到一條
另一條行業網關就出問題,返回錯誤代碼爲8,表示流量過大
條件:(7字節協議頭,TP_udhi=1, Pk_total Pk_number均爲1或者0或者和TP_udhi頭一致,Msg_Fmt爲ucs2)
能收到一條
另一條行業網關就出問題,返回錯誤代碼爲8,表示流量過大
後來才發現這個錯誤是本身形成的,我設了msg fmt,但Msg_content中的字節確仍是原來的gbk的
3.3)第三階段
改正了上面的錯誤以後,竟然ok了
此時的狀況是:
(7字節,TP_udhi=1, Pk_total Pk_number和udhi頭一致,msg fmt爲ucs2)
3.4) 舉個例子
我要發送AAABBBCCC,我拆成3條:AAA, BBB, CCC
3條分別以下
AAA :
Pk_total: 03
Pk_number: 01
TP_udhi: 01
Msg_Fmt: 08
Msg_Content: 06 08 04 00 39 03 01 00 41 00 41 00 41
BBB :
Pk_total: 03
Pk_number: 02
TP_udhi: 01
Msg_Fmt: 08
Msg_Content: 06 08 04 00 39 03 02 00 42 00 42 00 42
CCC :
Pk_total: 03
Pk_number: 03
TP_udhi: 01
Msg_Fmt: 08
Msg_Content: 06 08 04 00 39 03 03 00 43 00 43 00 43
注意TP_udhi 的協議頭中的XX XX 在這裏爲 00 39 是我隨機產生的。
4)結論
必須設置TP_udhi爲1
必須在Msg_contetnt前加入TP_udhi協議頭,協議頭我目前使用的是7字節的,我認爲6字節應該也能夠,你能夠試下
Pk_total,Pk_number是否必定設置的和TP_udhi協議頭中的MM NN 一致,我目前是一致,但我以爲不一致也能夠,就像普通短信中這個字段都爲1,你能夠試下
Msg_Fmt必定不能選擇15即gbk,我目前選的是8(UCS2),其餘的行不行,你能夠試下
感受到7字節仍是有好處的,特別是用了兩個字節XX XX 來標示一批短信,若是這兩個字節隨機產生(若是不隨機產生,實現成本要大不少),這使得在大併發的狀況下,衝突(某時刻某個手機接到的兩批短信批次相同會致使手機合併短信出問題)的可能性降低了不少。
最好能有個模擬網關測試下,雖然模擬僅模擬行業網關,但至少能避免我第二階段發生的愚蠢的錯誤,最好還能有個tcpdump工具,來檢測發送的字節是否正確。