短信接口平臺 [轉]
中國電信和中國移動的短信協議要求客戶端主動連接到網關收取信息,并且接受的連接只能有一個。因此客戶端的接收程序必須盡快處理收到的信息,好盡快接收下一個信息。而客戶端的程序又有很多事情必須處理,比如寫日志并分發給相關的應用。
開始我用多線程的方式,即接收程序收到從網關發來的信息后,啟動一個新線程處理收到的信息,本身接著收下一個信息。新啟動的線程負責寫日志,然后分發給相關的應用。這種方式運行起來效果不錯。
接著我又遇到一個問題,寫日志和分發給應用的程序是兩個不相關的東西,放在一起有點別扭。寫日志的程序對實時性要求不高,只要保證記錄了就可以;而分發程序需要盡量快,不應該等日志完了再執行。再起一個線程寫日志,一個線程分發?這樣線程多了反而更慢,不太好。
對 與從網關收到的信息我們可能有許多處理程序,比如一個是寫日志,一個是分發給應用。就日志來說,就有寫數據庫、寫文本文件、控制臺輸出等。所以我采用了消 息隊列的方式,這樣接收程序收到從網關來的信息后送出一個消息到消息隊列中,需要處理的程序自己來取就是了。這個消息隊列用的是 Topic/Subscribe模式,就是接收程序發出的同一個消息可能被多個處理程序接受。這樣對信息的不同處理,我就可以寫不同的消息處理程序。
接收完了,看看向網關發送信息的情況。短信網關一般也只允許一個連接進行發送,而且中國電信和中國移動使用的短信網關協議都是異步的,這樣用消息隊列的發送也很理想。
整體框架入下面這幅圖,
Transport Service 是和網關通訊的程序。它負責保持連接、發送信息給網關、接收網關來的信息,并把信息發送到消息隊列
Deliver Controller 是分發信息給相關應用的控制器。它從消息隊列中收取Deliver信息,然后根據信息的內容或者用戶的狀態,用不同的Application Deliver把信息分發給應用
Application Deliver 負責具體分發信息給應用。不同的應用可能要求不同的信息接受方式,比如多數是用HTTP方式,分發程序用POST方法把信息提交給應用,這中方式用的是 AppDeliverHttpPost;有的是用SOAP,用的就是AppDeliverSoap了。總之,要什么新方法,寫一個Application Deliver就可以了。
Logger 就是寫日志的程序。它從消息隊列中收取所以消息,然后寫日志。如果要有不同的日志方法可以寫不同的Logger,比如我有一個DBLogger,是向數據庫里寫日志的實現。
Sender 是通過Transport Service發送Submit信息給網關的程序。短信協議是異步的,但多數應該要求同步,就是要知道發送是否成功。因此Sender多提供了一個實現同步的方法。Sender發送后,從消息隊列中等待發送的結果,然后返回結果。
Web Service 是接受應用發送信息的接口。為什么要這個呢?和接收一樣,多數應用發送信息的時候是用HTTP的POST方法。而且這樣應該不應該知道短信協議的數據包格式,這樣同一個應該可以給不同的短信協議使用,比如中國電信的SMGP和中國移動的CMPP。
Application 就是最終處理短信的應用了。它和短信協議無關,比如我們有個游戲同時支持中國短信的小靈通和中國移動的GSM手機。另外給個Web的例子: http://www.hcmms.com.cn/greetings/
在實際實現中,我使用了J2EE。我本來對J2EE挺煩的,不過這次效果不錯,特別是它的JMS,正好適合我的需要。開始我自己做消息隊列管理,后來發現做Topic方式的實現比較麻煩,所以還是用現成的吧。Application Server選用了JRun或JBoss。因為這兩個用JMX,我比較容易寫自己的MBean放到作為應用服務的Service。
其 中Transport Service就是一個JMX的MBean。另外根據JRun和JBoss的要求,做了一下擴展,很順利的作為應用服務器中的一個服務執行了。為什么用 JMX?因為它比較容易管理,比如我要修改Transport Service的連接超時參數,用HttpAgentAdapter直接修改就可以了,服務本身就不用重新啟動。
Deliver Controller、Logger我都做成了MessageBean,好接收消息隊列。Sender和Application Deliver是Stateless的SessionBean,方便別人調用。
用 了EJB還一個好處是,我Deploy和Undeploy其中的某些Bean的時候,不影響到其他Bean提供服務。比如新做了一個 Application Deliver,直接Deploy后,這個功能就可以用了。其他服務都不需要重新啟動,有點Plug&Play的味道。
數據庫我用的是MySQL,我個人還是比較喜歡這個數據庫的。
Web CVS: http://cvs.dragonsoft.net/horde/chora/cvs.php/phs-smgp/
說明
-
和網關通訊的程序。它負責保持連接、發送信息給網關、把從網關接收到的信息發送到消息隊列。
-
分發信息給相關應用的控制器。它從消息隊列中收取Deliver信息,然后根據信息的內容或者用戶的狀態,用不同的ApplicationDeliver把信息分發給應用程序。
-
負責具體分發信息給應用。不同的應用可能要求不同的信息接受方式,比如多數是用HTTP方式,分發程序用POST方法把信息提交給應用, 這種方式用的是 AppDeliverHttpPost;有的是用SOAP,用的就是AppDeliverSoap了。總之,要什么新方法,寫一個ApplicationDeliver就可以了。
-
記錄日志的程序。它從消息隊列中收取所有消息,然后寫日志。如果要有不同的日志方法可以寫不同的Logger,比如我有一個SMGPPacketDBLogger,是向數據庫里寫日志的實現。
-
通過TransportService發送Submit信息給網關的程序。短信協議是異步的,但多數應該要求同步,就是要知道發送是否成功。因此Sender多提供了一個實現同步的方法,在Sender發送后,從消息隊列中等待發送的結果,然后返回這個結果。
-
接收應用發送信息的接口。為什么要這個呢?和接收一樣,多數應用發送信息的時候是用HTTP的POST方法。而且這樣應該不應該知道短信 協議的數據包格式,這樣同一個應該可以給不同的短信協議使用,比如中國電信的SMGP和中國移動的CMPP。
-
最終處理短信的應用。它可以和短信協議無關,比如我們有個游戲同時支持中國短信的小靈通和中國移動的GSM手機。
實現
源代碼
- Web CVS:
http://cvs.dragonsoft.net/horde/chora/cvs.php/phs-smgp/
http://cvs.dragonsoft.net/horde/chora/cvs.php/gsm-cmpp/
http://cvs.dragonsoft.net/horde/chora/cvs.php/cnuc-sgip/
To Checkout the sources of phs-smgp
cvs -d:pserver:anoncvs@cvs.dragonsoft.net:/opt/cvsroot/dragonsoft/phs-smgp login
cvs -z3 -d:pserver:anoncvs@cvs.dragonsoft.net:/opt/cvsroot/dragonsoft/phs-smgp co phs-smgp
posted on 2008-05-08 15:09 gembin 閱讀(782) 評論(0) 編輯 收藏 所屬分類: Wireless