iPhone/iOS开发推送C++服务端APNS源代码

原文转自http://blog.sina.com.cn/s/blog_68661bd80101p26l.html

网上关于C++服务端的APNS代码比较少,给我们后台人员找资料比较烦,凭现在网上的海量资料,PushMeBaby那个程序,PushNotificationDemo那个demo。加上我曾做过PHP,所以很容易就把推送用那两种方式下推送程序DEMO做出来,无论用开发证书还是产品证书,调通都不是难事。

  直接把源代码发出来吧。蛋疼的很,公司打不开网盘。生成不了连接,如果在我放上连接之前象要代码直接加我QQ915893620。补上了:
    http://www.kuaipan.cn/file/id_30491149655454589.htm

  推送的原理很简单,就是在操作系统上建立一个长连接的socket,然后轮询。只不过是苹果推送服务器与iOS手机操作系统之间的socket连接。为什么这么做,为了延长电池使用寿命,节省耗电量。如果没有这个功能,象安卓,要完成软件在随时随地接收到开发公司服务端的通知,那每个软件都要在后台运行一个socket,很明显,这将是很耗电,而且很耗费资源的事情。最简单的设想,能不能把这些socket统一到一个连接上面去,能随时随地接收到通知,又不至于耗电,于是乎有了推送。那为什么安卓的做不了,原因多方面,安卓开源,厂家众多,再加上谷歌在中国受限制,就造成目前安卓手机无法完美推送的现象。假如有一天,极光推送能代替谷歌统一安卓推送市场,无论什么手机,通过极光推送,全部都用极光推送那一条socket,对安卓手机用户来说,绝对是好事。

    一般同学绝对想用 PushMeBaby验证证书的可靠性,但是新手的话可能要注意几点,
   iPhone/iOS开发推送C++服务端APNS源代码_第1张图片
第一,用户电子邮件地址,一定要用你的appid邮箱。名称最好也用appid的用户名。如果设置的不对,就有可能造成生成不了token的现象。
   如果你的电脑上有两种证书,譬如象我电脑上同时存在企业帐号,和公司开发者帐号。千万别以为可以用用一个CSR,必须用两个不同的邮箱请求两次。也就是说,CSR邮箱必须跟证书所属的appid一样。如果你在程序中能收到token,那这步就是成功的。

第二,用 PushMeBaby做推送服务端,要注意,他那个序列号必须按照他原有的空格格式(假如你直接用的话)。然后开发证书生成的序列号,只能对应开发证书。如果第一次就想用产品证书时不可能的。因为你必须要等你的软件发布之后才能获取到产品序列号,然后才能在服务端以产品序列号进行调试。

第三,有可能你发现更换证书之后,会连不上苹果推送服务器,那一定要记住开发证书推送连接的地址和产品证书连接的地址是不一样的,而且很多语言,会计算连接地址长度的问题.
result = SSLSetPeerDomainName(context, "gateway.push.apple.com",30);
应该改成result = SSLSetPeerDomainName(context, "gateway.push.apple.com",22);  22指的是前面字符串的length

第四,如果你用开发证书的序列号,在以产品证书为服务端 PushMeBaby的程序上进行测试,你会发现,点击三次会崩溃。解决办法是你赶紧发布一个现在的软件,并用你的测试手机下载,让后台获取到序列号,再以这个序列号作为后台产品证书的调试序列号。其实办法就是第二点所说,但是这个问题当初困住了我。

第五,苹果推送C++服务端不是象php那样需要秘要证书与开发证书合成ck.pem。也不是象objc那样直接开发证书。在我跟那个后台C++工程师,实现的过程中。是以PushChatKey.pem和PushChatCert.pem作为分开的文件使用的。
PushChatKey.pem和PushChatCert.pem名字也可以任意修改

与苹果apns通信的证书怎么来的?需要iOS开发者提供给服务端的开发者
aps_production.cer从苹果开发者网站下载;

bogon:~chenshuangchou$ opensslx509 -in aps_production.cer -inform der -out PushChatCert.pem

得到PushChatCert.pem


双击安装aps_production.cer到钥匙串,在钥匙串中找到刚才安装的推送证书,点开,右键导出秘要,命名为XXX.p12;demo中是csc123.p12

bogon:~chenshuangchou$ opensslpkcs12 -nocerts -out PushChatKey.pem -in csc123.p12 

此处需要输入密码,demo中的密码:csc123

重复确认密码,得到PushChatKey.pem



第六,按我的理解,推送只是一个通知,代替不了socket,而且推送并非100%成功,成功率多少很大意义上取决于苹果推送服务器,你能做的是保证两条推送消息的间隔设置的够长。

@"{"aps":{"alert":"This is some fancymessage.","badge":1,"sound":"default"}}";

alert指地是弹出的内容,badge指地是软件在主界面icon的数字,sound指地是收到消息提示的声音。

起初我就想能否在发送推送的消息里面加上我要通信的socket指令,我尝试了一下,是可以携带指令内容,那能否在收到推送消息之后,立刻程序就处理指令呢。我找不到办法,后来想了想,程序都被关掉了,怎么在已经关掉的程序中写数据库。所以,我还是沿用了程序没有推送之前的询问接口,在软件启动或者激活时,获取那些推送的消息内容,很明显,后台要保存那些手机端未读取的消息。

[CSSLConnect::Connect] 
 pSockBIO Connect ERROR: error:14094414:SSLroutines:SSL3_READ_BYTES:sslv3 alert certificate revoked.
这个错误代表证书被移除,需要在苹果服务器上更新证书


Push的条件

1.必须要有苹果开发者账号。无论是企业账号还是公司账号或者是个人开发者账号,均能做推送。上一讲说过,苹果安全机制中用证书验证签名信息。推送也需要证书,而证书只能在开发者网站进行下载。

2.必须要有一个苹果系统,无所谓虚拟机,黑苹果还是原装苹果系统。推送证书的生成必须提供一个CSR文件,这个CRS文件包含该系统的标示与开发者账号信息,并在钥匙串生成密钥。

3.如果要测试推送,必须要准备一台iPhone,因为模拟器不支持推送。

push机制

推送消息就是一个socket连接,这个socket连接发送到apns(苹果消息推送服务器)。然后由apns发送消息到手机,在用户打开消息时,跳转到相应的app软件。(见图)

阶段一:Provider[服务端]把要发送的消息,目的IOS设备标识打包,发送给APNS

阶段二:APNS在自身的已注册Push服务的IOS设备列表中,查找有相应标识的IOS设备,并将消息发送到IOS设备;

阶段三:IOS设备把发送的消息传递给对应的应用程序,并且按照设定弹出Push通知。

证书配置

1.包含推送的功能的app,在开发者网站上创建AppIDs时,必须使用明确的appidExplicitApp ID)作为签名的前缀,不能使用带有*WildcardApp ID

2.并在AppServices中启用PushNotifications功能,然后为这个Appid创建一个证书。创建证书需要用钥匙串从颁发机构请求证书,填写开发者账号邮箱和用户名,生成CRS文件。推送通知的证书有两种,一种是开发SSL证书,一种是产品SSL证书。

 

证书区别

两种证书的区别:

1、开发证书可以在软件开发时就能获得token,而发布证书必须在软件发布之后才能获得。在程序开发过程中开发证书就可以推送,而发布证书不行。

 

2、开发证书在推送消息时,连接apns的地址是gateway.sandbox.push.apple.com,而发布证书连接的是gateway.push.apple.com


消息设置

 

[[UIApplication sharedApplication]registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert |UIRemoteNotificationTypeBadge |UIRemoteNotificationTypeSound)];

//判断程序是不是由推送服务完成的

if (launchOptions) {

    NSDictionary*pushNotificationKey = [launchOptionsobjectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];

   if (pushNotificationKey) {

       [selfalertNotice:@""withMSG:@"这是通过推送窗口启动的程序,你可以在这里处理推送内容"cancleButtonTitle:@"知道了"otherButtonTitle:nil];

    }

}

 

- (void)application:(UIApplication *)appdidRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {

    

}

 

 

- (void)application:(UIApplication *)appdidFailToRegisterForRemoteNotificationsWithError:(NSError *)err {

}

//程序处于启动状态,或者在后台运行时,会接收到推送消息,解析处理

- (void)application:(UIApplication *)applicationdidReceiveRemoteNotification:(NSDictionary *)userInfo

 

{

}


你可能感兴趣的:(推送c服务端,ios推送c服务端,ios开发推送c,ios开发推送,苹果c服务端推送)