APNS消息推送(node.js實現)
一、 推送流程
步驟:
1.應用程序需要激活推送通知功能。在使用之前,用戶需要確認他是否願意接受這些推送功能。
2.IOS跟APNSServer要deviceToken,應用程序接到一個“devicetoken”。你可以認爲“devicetoken”是推送通知發送信息的目的地址。
3.應用程序會將“devicetoken”發送給PUSH服務端程序(Provider)。
4.當你的應用程序發生了有趣的事情,你的服務器向“蘋果推送通知的服務器(ApplePush Notification Service,縮寫,APSN)”發送通知。
5.APNS服務將消息通知發送到用戶的設備(例如,iPhone,iPad等)的應用程序。
備註:
產品發佈APNS服務器,gateway.push.apple.com
測試APNS服務器,gateway.sandbox.push.apple.com
二、 獲取證書,無論是客戶端和APNS,還是Provider和APNS,都需要通過證書進行連接
提示:
(1)需要申請Apple開發者帳號,準備一臺真實設備。模擬器沒有DeviceToken,不能測試APNS;
(2)收到提醒時,如果程序在前臺打開會看不到提醒。
1)在Apple開發者中心創建AppID
創建時勾選AppServices-PushNotifications。AppID Suffix選擇通用AppID(Wildcard App ID)還是固定AppID(Explicit App ID)都可以,如果要開發多個App可以選擇通用AppID。創建成功後在Identifiers-AppIDs可以查看,點擊之前創建的AppID,在展開的菜單中點擊[Settings]按鈕進入配置界面。
在配置界面中找到PushNotifications,點擊[CreateCertificate...]按鈕創建SSL證書。DevelopmentSSL Certificate 和 ProductionSSL Certificate對應開發環境和生產環境,選擇DevelopmentSSL Certificate。
備註:也可以點擊左側導航菜單的Certificates,來添加一個APNs證書。選擇ApplePush Notification service SSL (Sandbox),之後的步驟相同。
2) 生成CSR(證書請求)文件
在Mac系統中打開實用工具-鑰匙串-鑰匙串訪問-證書助理-從證書頒佈機構請求證書,填入郵箱和名稱,選擇[存儲到磁盤],得到一個名爲CertificateSigningRequest.certSigningRequest的證書請求文件,同時會在登陸- 密鑰裏新增兩條紀錄,一個公用密鑰和一個專用密鑰:
回到Apple開發者中心的網頁,點擊[Continue]繼續,上傳生成的CertificateSigningRequest.certSigningRequest文件。完成這一步就可以得到.cert文件了。
3)App開發過程中要在真實設備上調試,需要DevelopmentProvisioning profile和DevelopmentCertificate。
在 左側導航菜單-Devices,添加一個ios設備。UUID可以在iTunes裏查到。然後增加一個iOSApp Development的Certificate和ProvisioningProfile:
4)最後得到一個證書文件,和一個.mobileprovision後綴的文件,就是ProvisioningProfile文件了。
安裝證書文件,將.mobileprovision文件通過Xcode導入設備中。一般連接iso設備時Xcode會自動彈出,也可以在Xocde菜單的Help-Xcode Help-Devices修改ProvisioningProfile文件。下圖是在Apple開發者中心創建的ProvisioningProfile:
備註:要保證AppID和程序的TargetProperies-Bundleidentifier的值相同,否則會報錯。
5)安裝
切換到左側導航菜單的Certificates,找到之前生成的APNsDevelopmentiOS證書,點擊[Download]按鈕下載,得到aps_development.cer。安裝後,在鑰匙串訪問中找到對應的證書。
6)導出Provider需要的證書和專用密鑰
選中AppleDevelopment IOS Push Services: org.dmyz.app上點擊右鍵,選擇[導出AppleDevelopment IOS Push Services:org.dmyz.app],文件格式切換成.cer,導出爲cert.cer。點擊左側▶展開它,可以看到名爲dmyz,類別爲[專用密鑰]的這個子項,選中導出爲key.p12。
7)將導出的文件進行openssl處理
方法一:
opensslx509 -in cert.cer -inform DER -outform PEM -out cert.pem
opensslpkcs12 -in key.p12 -out key.pem -nodes
備註:會要求輸入importPassword,如果導出時沒有設置則爲空
方法二:
opensslpkcs12 -clcerts -nokeys -out cert.pem -in cert.p12
opensslpkcs12 -nocerts -out key.pem -in key.p12
cat cert.pem key.pem >key.pem
備註:主要差別是key沒有加nodes參數,最後把兩個文件合併了。測試過可以通過。執行第二條命令時需要輸入PEMpass phrase,至少4個字符。
現在得到key.pem和cert.pem文件了,無論服務是NodeJS,Python還是Ruby,這只需要這兩個文件。
三、 推送程序
1)客戶端:通知計數、點擊通知執行的函數等細節設置和Locationnotification相同,區別是要指定Device。Xcode中打開項目的AppDelegate.m文件中增加一個函數,來獲取設備Token:
(void)application:(UIApplication*)applicationdidRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken{
NSLog(@"deviceToken: %@", deviceToken); }
2)服務器端:
安裝apn,把key.pem和cert.pem拷貝到項目目錄(也可不用,可在程序中指定路徑即可)。
varapn=require('apn');
var token = '7eda0e6e775f50f7da3998423c8bd06a0ca505213ec241b22d2507b626dd6498'; //長度爲64的設備Token,去除空格 var options = { "cert": "/..../cert.pem", //cert.pem文件的路徑 "key": "/..../key.pem", //key.pem文件的路徑 "gateway": "gateway.sandbox.push.apple.com", "port": 2195}, apnConnection = new apn.Connection(options), device = new apn.Device(token), note = new apn.Notification(); note.expiry = Math.floor(Date.now() / 1000) + 60; note.badge = 3; note.alert = 'test APNS '; note.sound = 'default'; note.payload = {'messageFrom': 'Caroline'}; note.device = device; apnConnection.pushNotification(note, device);
還可添加相應的事件處理:
apnConnection.on('connected',function() {
console.log("Connected");
});
apnConnection.on('transmitted',function(notification, device) {
console.log("Notificationtransmitted to:" + device.token.toString('hex'));
});
apnConnection.on('transmissionError',function(errCode, notification, device) {
console.error("Notificationcaused error: " + errCode + " for device ", device,notification);
});
apnConnection.on('timeout',function () {
console.log("ConnectionTimeout");
});
apnConnection.on('disconnected',function() {
console.log("Disconnectedfrom APNS");
});
apnConnection.on('socketError',console.error);
運行服務器程序,客戶端即可收到推送消息。