日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

[转]宝文!Apple Push Notification Service (APNS)原理与实现方案

發(fā)布時(shí)間:2023/12/10 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [转]宝文!Apple Push Notification Service (APNS)原理与实现方案 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

原理

簡(jiǎn)單的說(shuō),app要單獨(dú)實(shí)現(xiàn)消息動(dòng)態(tài)更新,一種是輪詢(xún),這對(duì)用戶(hù)來(lái)說(shuō)會(huì)帶來(lái)額外的流量。另一種方案是push,app client和server直接保持一個(gè)長(zhǎng)連接,有新的消息時(shí)server push給app client。

這兩種通過(guò)app自身實(shí)現(xiàn)的“push”都會(huì)面臨以下問(wèn)題:

  • 進(jìn)程被關(guān)閉后無(wú)法在發(fā)送請(qǐng)求
  • 大量app開(kāi)啟網(wǎng)絡(luò)連接對(duì)用戶(hù)的流量和電池都會(huì)帶來(lái)大量消耗
  • 通訊安全問(wèn)題需要app自己提供解決方案
  • APNS為app開(kāi)發(fā)商提供了一個(gè)統(tǒng)一的消息通知平臺(tái)。apple和每個(gè)iOS設(shè)備之間保持一個(gè)長(zhǎng)連接。開(kāi)發(fā)商將消息發(fā)送給APNS,APNS將該消息發(fā)送到指定的iOS設(shè)備,iOS設(shè)備展示消息、啟動(dòng)相應(yīng)的app。


    從以上過(guò)程可知,為通過(guò)APNS實(shí)現(xiàn)消息push,一個(gè)消息需要標(biāo)識(shí)發(fā)送到“哪臺(tái)iOS設(shè)備”的“哪個(gè)app”。這兩個(gè)分別由設(shè)備id(deviceToken)和SSL的證書(shū)文件(開(kāi)啟消息push的app需要配置一個(gè)SSL證書(shū))標(biāo)識(shí)。消息結(jié)構(gòu)體如下:

    實(shí)現(xiàn)方案

    詳細(xì)過(guò)程請(qǐng)參考http://mobiforge.com/developing/story/programming-apple-push-notification-services,一步步來(lái)即可。這一過(guò)程會(huì)生成文件:

  • CertificateSigningRequest.certSigningRequest 用于生成SSL證書(shū)的中間文件,用后可刪除
  • aps_developer_identity.cer SSL證書(shū)文件,這一證書(shū)會(huì)關(guān)聯(lián)app id,利用該證書(shū)可將消息發(fā)送到對(duì)應(yīng)的app。
  • [xxx].mobileprovision和上述SSL證書(shū)文件綁定的app provision文件,請(qǐng)安裝到測(cè)試設(shè)備。
  • 雙擊aps_developer_identity.cer將證書(shū)文件導(dǎo)入到Keychain Access。

    java/php/c++需要的SSL證書(shū)和密鑰生成如下:

  • 將keychain access中的aps_developer_identity.cer導(dǎo)出為[xxx].p12
  • 終端下執(zhí)行:
    1 openssl pkcs12 -in [xxx].p12 -out [xxx].pem -nodes
  • 將最終生成的pem文件提供給后臺(tái)server

    后臺(tái)代碼示例

    app client請(qǐng)參考上述鏈接中的示例。

    push server:

    object c版本?http://stefan.hafeneger.name/download/PushMeBabySource.zip

    java版本?http://code.google.com/p/javapns/

    php版本?http://code.google.com/p/apns-php/

    現(xiàn)在后臺(tái)技術(shù)主要還是c/c++吧,網(wǎng)上一直沒(méi)找到合適的,自己實(shí)現(xiàn)demo,代碼如下:

    /*** @file main.cpp* @author Maxwin* @description TestPushServer*/#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <openssl/ssl.h> #include <openssl/rand.h> #include <openssl/bio.h> #include <openssl/err.h> #include <openssl/x509.h>
    #include <netinet/in.h>// 證書(shū)文件 #define CERTFILE "max.pem"SSL *ssl; SSL_CTX *ctx;void error(const char *msg) {printf("[ERROR]:%s\n", msg);exit(1); }SSL_CTX *setup_client_ctx() {ctx = SSL_CTX_new(SSLv23_method());if (SSL_CTX_use_certificate_chain_file(ctx, CERTFILE) != 1) {error("Error loading certificate from file\n");}if (SSL_CTX_use_PrivateKey_file(ctx, CERTFILE, SSL_FILETYPE_PEM) != 1) {error("Error loading private key from file\n");}return ctx; }// 將deviceToken字符串轉(zhuǎn)成對(duì)應(yīng)的binary bytes void token2bytes(const char *token, char *bytes) {int val;while (*token) {sscanf(token, "%2x", &val);*(bytes++) = (char)val;token += 2;while (*token == ' ') { // skip space++token;}} }// 打包消息 unsigned long packMessage(char *message, const unsigned char command, const char *tokenBytes, const char *payload) {unsigned long payloadLength = strlen(payload);unsigned short networkTokenLength = htons(32);unsigned short networkPayloadLength = htons(payloadLength);memcpy(message, &command, sizeof(unsigned char));message += sizeof(unsigned char);memcpy(message, &networkTokenLength, sizeof(unsigned short));message += sizeof(unsigned short);memcpy(message, tokenBytes, 32);message += 32;memcpy(message, &networkPayloadLength, sizeof(unsigned short));message += sizeof(unsigned short);memcpy(message, payload, payloadLength);return payloadLength + 37; }int push(const char *token, const char *payload) {char tokenBytes[32];char message[293];unsigned long msgLength;token2bytes(token, tokenBytes);msgLength = packMessage(message, 0, tokenBytes, payload);return SSL_write(ssl, message, (int)msgLength); }int main (int argc, const char * argv[]) {char token[] = "2b2474e5 ac7670f3 08fabf3a 9c1d1295 ed50e9aa f11b941a d6e3d213 4f535408";char payload[] = "{\"aps\":{\"alert\":\"Hello world!!!\",\"badge\":1}}";char payload2[] = "{\"aps\":{\"alert\":\"Hello kitty!!!\",\"badge\":12}}";char host[] = "gateway.sandbox.push.apple.com:2195";BIO *conn;// initSSL_library_init();ctx = setup_client_ctx();conn = BIO_new_connect(host);if (!conn) {error("Error creating connection BIO\n");}if (BIO_do_connect(conn) <= 0) {error("Error connection to remote machine");}if (!(ssl = SSL_new(ctx))) {error("Error creating an SSL contexxt");}SSL_set_bio(ssl, conn, conn);if (SSL_connect(ssl) <= 0) {error("Error connecting SSL object");}printf("SSL Connection opened\n");// push messageint ret = push(token, payload);printf("push ret[%d]\n", ret);// push [Hello kitty] after 5ssleep(5);ret = push(token, payload2);printf("push2 ret[%d]\n", ret);printf("Close SSL Connection\n");SSL_shutdown(ssl);SSL_free(ssl);SSL_CTX_free(ctx);return 0; }

    編譯運(yùn)行:

    g++ main.cpp -o pushServer -lssl -lcrypto

      

    ?

    轉(zhuǎn)載于:https://www.cnblogs.com/lihaozy/archive/2013/02/25/2931860.html

    總結(jié)

    以上是生活随笔為你收集整理的[转]宝文!Apple Push Notification Service (APNS)原理与实现方案的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。