最近因為某些項目的原因,需要實現(xiàn)WapPush的功能,本想偷懶在網(wǎng)上搜索一下,看有沒有合適的內(nèi)容,結(jié)果找不到一個合適的.只好自已動手來寫一個. 看了一下PAP協(xié)議的內(nèi)容,其實也并不復(fù)雜,屬于HTTP協(xié)議的擴展,因此,使用.NET的HttpWebRequest類庫便可以方便的實現(xiàn)PAP
最近因為某些項目的原因,需要實現(xiàn)WapPush的功能,本想偷懶在網(wǎng)上搜索一下,看有沒有合適的內(nèi)容,結(jié)果找不到一個合適的.只好自已動手來寫一個.
看了一下PAP協(xié)議的內(nèi)容,其實也并不復(fù)雜,屬于HTTP協(xié)議的擴展,因此,使用.NET的HttpWebRequest類庫便可以方便的實現(xiàn)PAP的通訊層.剩下的工作便是PAP協(xié)議內(nèi)容的組合了,PAP協(xié)議主要有四個方法及一個交互方法,分別是:
如果需要接收PPG(推送代理網(wǎng)關(guān))返回的發(fā)送結(jié)果通知消息,則需要提供一個回調(diào)地址,供PPG發(fā)送通知響應(yīng).PI(推送發(fā)起人)與PPG之間的關(guān)系如下圖:
PI端與PPG之間使用PAP協(xié)議通訊,PPG則調(diào)用空中協(xié)議傳送到手機端.
上圖則是PI發(fā)送一個WapPush信息,PI與PPG之間的交互過程
對于Cancel a Push, Query for status of a Push , Query for wireless device capabilities 這三種方式,都是PI與PPG之間的交互,即發(fā)起請求,得到響應(yīng)的方式,因此,不作詳細(xì)說明.
PAP協(xié)議的消息體是采用多段的方式提交請求的,即Content-Type類型為"multipart/related",到于具體的信息,可以參考RFC2387.整個PAP協(xié)議包包括三種結(jié)構(gòu),分別為
除了推送消息需要使用到三種消息以外,其它請求方法都只使用到控制實體包。這三種類型的包都是MIME類型格式,下面是一個請求包的具體格式
Content-Type: multipart/related; boundary=asdlfkjiurwghasf;
type="application/xml"
--asdlfkjiurwghasf
Content-Type: application/xml
"http://www.wapforum.org/DTD/pap_2.0.dtd"
[]>
..control for PPG..
--asdlfkjiurwghasf
Content-Type: text/vnd.wap.si
..Service Indication push message example..
--asdlfkjiurwghasf
Content-Type: application/xml
..assumed client capabilities..
--asdlfkjiurwghasf--
控制實體的定義如下
| push-response
| cancel-message
| cancel-response
| resultnotification-message
| resultnotification-response
| statusquery-message
| statusquery-response
| ccq-message
| ccq-response
| badmessage-response) >
product-name CDATA #IMPLIED
>
它一共支持11種控制命令,這些命令都必須放在PAP節(jié)點下面,如:
支持的11種控制命令分別如下:
push-message :PI -> PPG ,發(fā)起一個Push請求
push-response :PPG -> PI,PPG對Push請求的響應(yīng)結(jié)果
cancel-message :PI->PPG,取消消息的請求
cancel-response :PPG -> PI,PPG對取消請求的響應(yīng)結(jié)果
resultnotification-message :PPG->PI,結(jié)果提醒消息,由PPG調(diào)用通過PUSH消息時提供的通知地址傳送
resultnotification-response:PI->PPG,PI端對PPG的結(jié)果提醒消息的響應(yīng)
statusquery-message :PI->PPG,狀態(tài)查詢消息,查詢發(fā)送消息的當(dāng)前狀態(tài)
statusquery-response :PPG->PI,PPG對查詢請求的響應(yīng)結(jié)果
ccq-message :PI->PPG,發(fā)起一個終端能力查詢請求
ccq-response :PPG->PI,PPG對終端能力查詢的響應(yīng)結(jié)果
badmessage-response:PPG->PI,PPG在接收到錯誤請求包的時候,返回的響應(yīng)信息
結(jié)構(gòu)定義如下:
push-id CDATA #REQUIRED
replace-push-id CDATA #IMPLIED
replace-method ( pending-only | all ) "all"
deliver-before-timestamp %Datetime; #IMPLIED
deliver-after-timestamp %Datetime; #IMPLIED
source-reference CDATA #IMPLIED
ppg-notify-requested-to CDATA #IMPLIED
progress-notes-requested ( true | false ) "false"
>
address-value CDATA #REQUIRED
>
priority ( high | medium | low ) "medium"
delivery-method ( confirmed | preferconfirmed
| unconfirmed | notspecified ) "notspecified"
network CDATA #IMPLIED
network-required ( true | false ) "false"
bearer CDATA #IMPLIED
bearer-required ( true | false ) "false"
>
push-message節(jié)點是推送一個消息的控制節(jié)點,它有多個屬性,含義如下:
push-id:推送流水ID,由PI端創(chuàng)建管理,需要全局唯一,返回響應(yīng)包、通知包會根據(jù)此ID來判斷請求
replace-push-id:替換推送ID,指被替換的舊PushID,多用于使用新的消息替換以提交卻未發(fā)送的消息
replace-method:替換的方法,有pending-only和all兩種選項可選,all表示替換舊消息的所有接收者,pending-only則表示替換有可能被取消的接收者
deliver-before-timestamp:發(fā)送終止時間,指超過指定的時間則不發(fā)送消息了,格式為標(biāo)準(zhǔn)的UTC時間:YYYY-MM-DDThh:mm:ssZ
deliver-after-timestamp:發(fā)送的開始時間,須在指定的時間才能開始發(fā)送,格式為標(biāo)準(zhǔn)的UTC時間:YYYY-MM-DDThh:mm:ssZ
source-reference:內(nèi)容提供者的文本名稱,PPG網(wǎng)關(guān)可能需要此參數(shù)判斷PI的權(quán)限及能力
ppg-notify-requested-to:PPG發(fā)送結(jié)果響應(yīng)請求的Url地址
progress-notes-requested:是否在響應(yīng)包中包括處理日志信息
address節(jié)點需要包括在push-message節(jié)點下,如果有多個接收人,則增加多個address節(jié)點即可,address-value是實際的接收地址,它可以是一個邏輯地址,具體的格式大致如下:
wappush=12345678/type=PLMN@ppg.operator.com
quality-of-service節(jié)點也須要放在push-message節(jié)點下,它描述了當(dāng)前消息的各種發(fā)送屬性,如:優(yōu)先級、使用網(wǎng)絡(luò)、承載體等,不同的網(wǎng)絡(luò)或許有不同的參數(shù),請咨詢相應(yīng)的運營商。
具體的參數(shù)說明可以參考標(biāo)準(zhǔn)文檔:wap-247
push-id CDATA #REQUIRED
sender-address CDATA #IMPLIED
sender-name CDATA #IMPLIED
reply-time %Datetime; #IMPLIED
>
push-response是PI提交push-message到PPG后,PPG返回的響應(yīng)包結(jié)構(gòu),它有四個屬性,如下:
push-id:相關(guān)的push-id
sender-address:發(fā)送者地址,一般是PPG的地址
sender-name:發(fā)送者名稱,一般是PPG的名稱
reply-time:應(yīng)答時間,標(biāo)準(zhǔn)的UTC時間
progress-note節(jié)點不多介紹,是屬于處理日志節(jié)點
response-result節(jié)點包含了所發(fā)送消息的響應(yīng)結(jié)果,其定義如下:
code CDATA #REQUIRED
desc CDATA #IMPLIED
>
code是響應(yīng)的結(jié)果,具體可參考標(biāo)準(zhǔn)文檔的說明,desc則是相應(yīng)的描述信息
對于其它幾個請求結(jié)構(gòu)相對簡單,此處不再說明,參考標(biāo)準(zhǔn)文檔即可。
PAP協(xié)議是基于HTTP協(xié)議,因此,建立一個PAP協(xié)議只需要發(fā)起一個HTTP請求即可,截取一段發(fā)送代碼如下:
Code
//Pap請求
HttpWebRequest papRequest = (HttpWebRequest)HttpWebRequest.Create(Config.ServiceUrl);
papRequest.Method = "POST";
papRequest.ContentType = "multipart/related; type=application/xml;boundary=" + IRequest.Boundary;
papRequest.Headers.Add("Authorization", Config.EncPass);
byte[] papData = rqeuestObj.GetBytes(Config.enc);
Stream requestStream = papRequest.GetRequestStream();
requestStream.Write(papData, 0, papData.Length);
requestStream.Close();
HttpWebResponse response = (HttpWebResponse)papRequest.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream(), Config.enc);
ret = ReplaceXml(sr.ReadToEnd());
sr.Close();
主要設(shè)置幾個屬性,分別為Method、ContentType以及Authorization,對于前兩個不作說明,Authorization則表示認(rèn)證信息,有些PPG網(wǎng)關(guān)不需要認(rèn)證信息,因此可以忽略這個屬性。認(rèn)證屬性的值為Base64編碼的字串,格式為:Base base64String
用戶名和密碼以這樣的格式編寫:UserName:Password,然后對這個串進(jìn)行編碼,放在Base 后面即可。表示基本的Base64認(rèn)證串。對于其它的代碼就不多做解釋了:)大家可以看源碼。
目前僅實現(xiàn)了PAP協(xié)議的解析、生成等功能,未實現(xiàn)對數(shù)據(jù)發(fā)送的隊列控制、流量控制等等,這些都需要進(jìn)一步完善,如果各位有興趣完善的話,希望也提交到項目里面咯:)
下載地址:http://paplib.codeplex.com/
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com