當前位置:商標查詢大全網 - 網遊競技 - 怎樣編寫Apple Push Notification服務器

怎樣編寫Apple Push Notification服務器

基本結構:

使用唯壹的SSL許可證連接到APNS

循環通過妳需要發送到消息

為各消息構建有效載荷

斷開與 APNS的連接

遠程通知數據的流程是單向的。提供者將包括客戶程序設備令牌和有效載荷的數據打包,發送到APNS,然後APNS再將通知發送給最終設備。

限制:

有效載荷限制為256字節 – 它包括了消息主體以及妳希望傳送帶其他屬性。推送通知並不適於傳送大量的數據。例如,我們僅僅傳送壹條短消息通知服務器監視的事件已經被觸發了。

APNS並不提供消息發送成功與否的回饋狀態。壹個原因是如果壹個設備無法聯系那麽發送給它的消息將被存於隊列中,然而只有最新發送的消息被存於隊列中 – 覆蓋了先前發送但不成功的消息。

推送通知不適合用於發送緊急通知,因為消息僅在設備具有wifi或手機服務連接的情況下才能被發送,這也是為什麽我們推薦與其它方法如email或SMS壹起使用的原因。

用來與APNS通訊的SSL許可證(下面將討論)是在程序層生成的。本教程涉及到實現方法僅適於單個iPhone程序,所以如果妳有多個程序,那麽妳需要修改代碼使之適合於使用多個許可證。

設備令牌:

每條推送消息都必須針對某特定設備。這是通過使用在妳的iPhone程序中由APNS產生的唯壹deviceToken(設備令牌)來實現的。壹旦獲取了此令牌,妳需要將其存儲於服務器而不是妳的iPhone程序內。它看上去像這樣:

c9d4c07c fbbc26d6 ef87a44d 53e16983 1096a5d5 fd825475 56659ddd f715defc

在我們的 Server Density iPhone 程序中,我們在程序啟動時調用相應的令牌生成方法,然後通過 HTTP API 調用 傳回給我們的服務器 。這將使得deviceToken存儲於服務器的有關用戶的數據庫中,從而我們可以使用它與持有此設備的用戶進行通訊。

反饋服務:

Apple 還提供了壹個 反饋服務 ,妳應該定期查詢。它提供了壹個以前使用過但不再有效的(例如用戶卸載了妳的iPhone程序)設備令牌列表。妳可以從妳的數據庫中刪除這些設備令牌。

許可證:

要進行推送服務的第壹件事就是獲取推送許可證。它用來對妳通過SSL與APNS通訊進行識別。

在Mac上生成 Apple推送通知SSL許可證:

登錄到 iPhone Developer Connection Portal 並點擊 App IDs

創建壹個不使用通配符的 App ID 。通配符 ID 不能用於推送通知服務。例如,我們的iPhone程序ID像這樣: ?AB123346CD.com.serverdensity.iphone

點擊App ID旁的“Configure”,然後按下按鈕生產 推送通知許可證。根據“向導”指導的步驟生成壹個簽名並上傳,最後下載生成的許可證。此步驟在 Apple文檔中 也有談到。

通過雙擊.cer文件將妳的 aps_developer_identity.cer 引入Keychain中。

在Mac上啟動 Keychain助手,然後在login keychain中選擇 Certificates分類。妳將看到壹個可擴展選項“Apple Development Push Services”

擴展此選項然後右擊“Apple Development Push Services” > Export “Apple Development Push Services ID123”。保存為 apns-dev-cert.p12 文件。

擴展“Apple Development Push Services” 對“Private Key”做同樣操作,保存為 apns-dev-key.p12 文件。

需要通過終端命令將這些文件轉換為PEM格式:

openssl?pkcs12?-clcerts?-nokeys?-out?apns-dev-cert.pem?-in?apns-dev-cert.p12

openssl?pkcs12?-nocerts?-out?apns-dev-key.pem?-in?apns-dev-key.p12

如果妳想要移除密碼,要麽在導出/轉換時不要設定或者執行:

openssl?rsa?-in?apns-dev-key.pem?-out?apns-dev-key-noenc.pem

最後,妳需要將鍵和許可文件合成為apns-dev.pem文件,此文件在連接到APNS時需要使用:

cat?apns-dev-cert.pem?apns-dev-key-noenc.pem?>?apns-dev.pem

將此文件保存為壹個易記的名字,妳有可能以後會用到它。上述步驟同樣適合於生成產品許可證。

載荷內容:

載荷 格式化為遵循 RFC 4627標準的JSON格式。它由以下幾部分組成:

提示 – 顯示於設備上的文本串

標識 – 設備屏幕中程序圖標上顯示的整數

聲音 – ?顯示消息在設備的同時發出的聲音的文本名字

本教程僅處理發送簡單提示文本串,但也可以發送包括諸如顯示自定義按鈕等在內的各種選項的字典集。

創建載荷:

使用 PHP 很容易根據數組並 轉換成 JSON而創建載荷:

$payload['aps']?=?array('alert'?=>?'This?is?the?alert?text',?'badge'?=>?1,?'sound'?=>?'default');

$payload?=?json_encode($payload);

顯示 $payload 的內容可以看到傳送到APNS 的 JSON字符串:

{

"aps"?:?{?"alert"?:?"This?is?the?alert?text",?"badge"?:?1,?"sound"?:?"default"?}

}

這將使消息顯示於設備上,觸發提升聲音並將“1”置於程序圖標上。默認按鈕“Close”和“View”同時會顯示於彈出窗口上。

對於 Server Density iPhone程序而言,讓用戶按下“View”直接進入產生此提示的服務器是很重要的,所以我們增加了額外的自定義值:

$payload['aps']?=?array('alert'?=>?'This?is?the?alert?text',?'badge'?=>?1,?'sound'?=>?'default');

$payload['server']?=?array('serverId'?=>?$serverId,?'name'?=>?$name);

$output?=?json_encode($payload);

當用戶按下“View”後,自定義server值將被傳遞到設備中的程序。JSON 值如下:

{

"aps"?:?{?"alert"?:?"This?is?the?alert?text",?"badge"?:?1,?"sound"?:?"default"?},

"server"?:?{?"serverId"?:?1,?"name"?:?"Server?name")

}

256字節的限制適用於整個載荷,包括自定義字典集。

原生接口

在Server Density中,壹旦產生了壹條提示,將建立壹個載荷並插入隊列中。因此有必要時我們可以同時發送多個載荷。

Apple推薦使用這種方法,因為如果妳在發送各載荷時頻繁連接和斷開,APNS有可能會封鎖妳的IP。

如Apple 描述:

原生接口使用原生socket,具有二進制內容,采用數據流技術,不產生回饋。

打開連接

打開連接的?PHP 5代碼如下:

$apnsHost?=?'gateway.sandbox.push.apple.com';

$apnsPort?=?2195;

$apnsCert?=?'apns-dev.pem';

$streamContext?=?stream_context_create();

stream_context_set_option($streamContext,?'ssl',?'local_cert',?$apnsCert);

$apns?=?stream_socket_client('ssl://'?.?$apnsHost?.?':'?.?$apnsPort,?$error,?$errorString,?2,

STREAM_CLIENT_CONNECT,?$streamContext);

如果發送錯誤,妳可以參考$errorString。它也包括了SSL許可證不正確時的詳細信息。

許可證文件處於執行的PHP代碼的當前工作目錄下,如果需要妳可指定其絕對路徑。

註意測試時應該使用開發許可證及sandbox。成品主機名為 gateway.push.apple.com ,而且妳必須使用不同的產品許可證。

發送載荷

在此,我們循環整個載荷隊列進行發送。構建發送到APNS的二進制內容簡單示例如下:

$apnsMessage?=?chr(0)?.?chr(0)?.?chr(32)?.?pack('H*',?str_replace('?',?'',?$deviceToken))?.?chr(0)?.

chr(strlen($payload))?.?$payload;

fwrite($apns,?$apnsMessage)

註意 $deviceToken 是從數據庫中提取並去除空格得到的。我們還應該檢查是否$payload超過256個字節。

$apnsMessage 包括了正確的二進制載荷,而fwrite 將載荷寫入當前活動的數據流連接中。

完成後,應關閉連接:

socket_close($apns);

fclose($apns);

php-apns

有壹個開源服務器庫php-apns實現了以上所有功能,它依賴於?memcached。我們不想使用任何第三方代碼,所以完全自己編寫了自己的服務器。我們使用自定義cron系統,幾秒鐘運行壹次。