我们的IOS移动应用要实现消息推送,告诉用户有多少条消息未读,类似下图的效果(笑果),特把APNS和Erlang相关解决方案笔记于此备忘.
 
   
   上面图片中是Apple Notification在UI展现的形式之一,Notification共有三种形式:图标显示更新数字(badge),提示信息(alert),提示音(sound);
 
   iOS Apple Push Notification Services (APNs)官方的开发文档位置在:[Apple Push Notification Services],iOS团队的Matthijs Hollemans写的入门文档:Apple Push Notification Services in iOS 6 Tutorial 从这两份文档中,可以了解APNs的设计和开发的各种细节.首先是APNS的设计初衷:当用户没有启动应用,或者没有开机那么应用Server想要推送的消息就无法到达,需要其他的机制来完成消息的投递.
 
  Apple Push Notification service (APNs)把消息推送到设备上,设备上有应用已经注册过要接受此类消息.这里会有三种角色:Provider, APNs,Device . 见下图:
 
   
  
 
     上图说明:消息提供者(Provider),Provider接入到APNs,把最新的消息推送到 APNs,然后由APNs推送到目标设备(Device)的指定应用(Client APP).
 
      从上面的图,可以提出很多问题,特别是考虑到一些极端情况的时候,很有意思,可以通过这些问题驱动阅读Apple开发文档:
  1. Provider,APNs,Device 这三者之间的信任关系是怎么建立?
  2. 如何标识消息是给哪台机器的哪个应用的?消息传递的协议是怎么设计的(如何承载要发送的消息)?
  3. 在Device离线的情况下,Provider提交N条要发送给该Device的消息到APNs,APNs如何处理?
  4. 对于一些极端情况:比如Device做了系统恢复,应用卸载,Device硬件损坏,APNs有哪些应对机制?
  
    首先解决三者的信任关系,Provider(APP Server)的开发方要从Apple Dev Center获得SSL证书, 每个证书一个应用,甚至开发和生产环境的证书都要分别申请. Provider要在APNs中进行认证注册,目前注册使用的是应用程序的唯一标识(bundle identifier).Provider Connection的是对应到指定应用的,certificate中包含了应用程序的标识信息(bundle ID),APNs维护了一个废弃列表,如果一个Provider上了名单,APNs就会移除对该应用的信任. Provider和APNs通信协议是二进制协议,使用TCP流协议建立SSL(TLS)安全连接,官方文档称这种信任为Connection Trust. 
 
    对于用户设备APNs使用的是Token Trust.用户安装一个APP的时候,如果APP需要消息推送功能通常在安装成功之后会经由用户设备发起注册请求,用户设备将此请求转发到APNs, APNs生成唯一的device certificate,其中包含了device token.Device Token 中包含了设备的唯一标识,使用Token key加密Device Token返回到Device.用户设备把device token返回给发起注册请求的应用程序,应用程序把Device Token的信息传递给Provider.用户设备上安装的APP从APNs 获得device token之后每一次连接到ANPs都要提供这个token. APNs解密device token并验证这个token是从连接过来的设备生成的:APNs保证实际连接过来的设备标识和certificate文件中里面包含的标识一致.
 
   Provider提交到APNS的notification两个必要的信息:把什么消息投递给谁,即包含设备标识(Device Token)和实际消息体(Payload).APNS使用token Key解密token,从中提取设备ID来决定最终消息投递到哪个设备.Device Token有一个非常贴切的类比:手机号,它包含的信息可以让APNs来定位安装了指定应用的设备.APNs还使用Device Token来路由消息,Payload的消息组织形式是类JSON的,它包含的信息包括推送给设备什么内容以及如何提示;Payload内容大小限制是 256 bytes.
  注意:Device Token和设备的UDID不是一回事,用户恢复系统,重装都会导致device token变化.
 
    APNs有一个 Feedback Service的设计,它维护应用消息推送失败的设备列表,如果应用已经卸载了就无法投递成功,这样Feedback Service里面就会有记录.Provider的开发方应定期从该服务拉取这个失败列表来调整自己的发送行为:不要再给一个总是失败的设备推送消息了.如果设备离线,notification会在APNs上保存有限的一段时间,设备上线之后完成推送.如果设备离线期间同一个应用推送了多条notification,那么只会保存最新的notification,如果设备长期离线,任何离线消息都会被抛弃掉.这样如果iPhone掉海里面,需要推送给它的消息在过期之后就会被清理掉,不会长久占用APNs的资源.
 
 
  
 
经过上面的分析基本可以列出Erlang实现消息推送的技术要点了:
[1] JSON数据解析构造 mochijson mochijson2之类的模块就可以搞定  mochijson:encode --> list_to_binary
[3] 二进制协议实现 (Apple Binary Iterface)
Packet = [<<1:8, MsgId/binary, Expiry:4/big-unsigned-integer-unit:8,
                32:16/big,
                BinToken/binary,
                PayloadLength:16/big,
                BinPayload/binary>>]
 
[4] deviceToken -> binary 需要hexstr_to_bin的方法,这个代码片段之前说过多次了
bin_to_hexstr(Bin) ->
lists:flatten([io_lib:format("~2.16.0B", [X]) ||
X <- binary_to_list(Bin)]). hexstr_to_bin(S) ->
hexstr_to_bin(S, []).
hexstr_to_bin([], Acc) ->
list_to_binary(lists:reverse(Acc));
hexstr_to_bin([X,Y|T], Acc) ->
{ok, [V], []} = io_lib:fread("~16u", [X,Y]),
hexstr_to_bin(T, [V | Acc]).
[5] 维护TCP连接,重连机制
 
按照上面的要点完成了基本的验证之后,在Github上找到了开源项目apns4erl (地址:https://github.com/inaka/apns4erl),这个项目对APNS服务做了良好的实现和封装.下面介绍下apns4erl的使用:
 
 

开源项目APNS4erl

 
证书制作:
  APP Server和Apple Server中间建立信任关系需要通过各种证书,apns4erl作者在项目中提供了生成证书的脚本,不过在项目首页提到.cer和.p12文件生成pem证书的脚本地址是错的,实际位置是:
 
执行下面的脚本就一步一步即可:

#!/bin/sh

# Usage:
# test_certs {cert_file} {private_key_file}
# Example:
# test_certs aps_developer_indetity.cer aps_developer_identity.p12 mkdir -p priv/temp
openssl pkcs12 -in "$2" -out priv/temp/key-enc.pem
openssl rsa -in priv/temp/key-enc.pem -out priv/temp/key.pem
openssl x509 -inform der -in "$1" -out priv/temp/cert.pem
cat priv/temp/cert.pem priv/temp/key.pem > priv/cert.pem
rm -rf priv/temp
make test
下面是测试代码,注意send_badge/1方法就是我们需要的效果:
-module(t).
-compile(export_all).
-define(APNS_NAME,app_apns). -include("apns.hrl").
-include("localized.hrl"). conn_apns() ->
ssl:start(),
apns:start(),
apns:connect(
?APNS_NAME,
fun handle_apns_error/,
fun handle_apns_delete_subscription/
). send_message()->
apns:send_message(?APNS_NAME, "devicetoken31d1df3a324bb72c1ff2bcb3b87d33fd1a2b7578b359fb5494eff", "hello,这是一号话务员"). send_message(Msg) ->
apns:send_message(my_connection_name, #apns_msg{
alert = Msg ,
badge = ,
sound = "beep.wav" ,
expiry = ,
device_token = "devicetoken31d1df3a324bb72c1ff2bcb3b87d33fd1a2b7578b359fb5494eff"
}). send_badge(Number)->
apns:send_badge(qiaoqiao_apns,"devicetoken31d1df3a324bb72c1ff2bcb3b87d33fd1a2b7578b359fb5494eff", Number). handle_apns_error(MsgId, Status) ->
error_logger:error_msg("error: ~p - ~p~n", [MsgId, Status]). handle_apns_delete_subscription(Data) ->
error_logger:info_msg("delete subscription: ~p~n", [Data]).
APNS相关资料:
 
 
[0] iOSDeveloper Library: Apple Push Notification Service (APNS)
 
[1] Apple Push Notification Services in iOS 6 Tutorial
 
[2]  Apple Push Notification Services in iOS 6 Tutorial 中文
 http://www.raywenderlich.com/zh-hans/24732
 
[3] iOS 和 Android 的后台推送原理各是什么?有什么区别?
 
[4] 苹果产品是如何实现推送功能的呢?
 
[5] 为什么 Android 的后台推送不如 iOS 的推送使用广泛?
 
[6]  Is the device token as unique as the device ID?
 
[7]  If the user restores backup data to a new device or computer, or reinstalls the operating system, the device token changes. https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/IPhoneOSClientImp.html
 
[8] Apple Push Notifications with Erlang
 
[9] Sending Apple Push Notifications with Erlang
 
最后小图一张:
 

[Erlang 0106] Erlang实现Apple Push Notifications消息推送的更多相关文章

  1. 使用Google Cloud Messaging (GCM),PHP 开发Android Push Notifications (安卓推送通知)

    什么是GCM? Google Cloud  Messaging (GCM) 是Google提供的一个服务,用来从服务端向安卓设备发送推送通知. GCM分为客户端和服务端开发. 这里我们只介绍服务端开发 ...

  2. (转)在SAE使用Apple Push Notification Service服务开发iOS应用, 实现消息推送

    在SAE使用Apple Push Notification Service服务开发iOS应用, 实现消息推送 From: http://saeapns.sinaapp.com/doc.html 1,在 ...

  3. Push:iOS基于APNS的消息推送

    1. Push的三个步骤,如下图所示: (1)Push服务应用程序把要发送的消息.目的iPhone的标识打包,发给APNS: (2)APNS在自身的已注册Push服务的iPhone列表中,查找有相应标 ...

  4. [置顶] 手把手教你iOS消息推送证书生成以及Push消息

    iOS推送消息是许多iOS应用都具备的功能,今天在给应用加推送功能,在生成证书的过程中,发生了各种令人蛋痛的事.下面就把步骤拿出来分享下: iOS消息推送的工作机制可以简单的用下图来概括: Provi ...

  5. 了解iOS消息推送一文就够:史上最全iOS Push技术详解

    本文作者:陈裕发, 腾讯系统测试工程师,由腾讯WeTest整理发表. 1.引言 开发iOS系统中的Push推送,通常有以下3种情况: 1)在线Push:比如QQ.微信等IM界面处于前台时,聊天消息和指 ...

  6. 为友盟消息推送开发的PHP SDK(composer版):可以按省发Android push

    一直以来APP希望按省市县推送Android push,只能自己分析用户经纬度,打tag发送. 现在终于有服务商提供了. 友盟消息推送 可以“按省推送”,很方便. 我为友盟做了PHP SDK(comp ...

  7. 带你了解什么是Push消息推送

    前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 如果有看我最近文章的同学可能就知道我在公司负责的是一 ...

  8. APP消息推送机制的实现(PUSH)

    出于好奇,想了解一下消息推送机制,在网上搜索到了几篇文章,感觉还不错,粘贴下来,等真正用到的时候再仔细研究 以下两篇是关于ios的 1.http://blog.csdn.net/xyxjn/artic ...

  9. 采用MQTT协议实现android消息推送(2)MQTT服务端与客户端软件对比、android客户端示列表

    1.服务端软件对比 https://github.com/mqtt/mqtt.github.io/wiki/servers 名称(点名进官网) 特性 简介 收费 支持的客户端语言 IBM MQ 完整的 ...

随机推荐

  1. 【记录】ASP.NET MVC RegisterBundles

    1. Install the package from nuget Install-Package Microsoft.AspNet.Web.Optimization 2,BundleConfig 配 ...

  2. @Async in Spring--转

    原文地址:http://www.baeldung.com/spring-async 1. Overview In this article we’ll explore the asynchronous ...

  3. C/C++ 双精度double 数据相加出错缺陷解释

    不知道有没有人和我一样遇到过这样一个问题,请看下面代码. #include<iostream> using namespace std; int main(){ double a=2.3, ...

  4. ASP.NET网站优化(转自一位博友的文章,写的非常好)

    不修改代码就能优化ASP.NET网站性能的一些方法 阅读目录 开始 配置OutputCache 启用内容过期 解决资源文件升级问题 启用压缩 删除无用的HttpModule 其它优化选项 本文将介绍一 ...

  5. 魔方渗透系统安装VMtools教程

    虚拟机魔方渗透系统安装VMtools教程 1.开机登陆后,如图点击安装VMtools. 2.进入media文件夹: cd /media   查看mdia文件夹内容: ls   3.打开VMware T ...

  6. MongoDB - basic

    mongoDB basic from:http://www.tutorialspoint.com/mongodb prject:https://github.com/chenxing12/l4mong ...

  7. Java进击C#——语法之ADO.NET

    本章简言 上一章讲到关于C#语法的基础部分.了解相关的基础部分之后我们就要去了解一下C#是什么样子访问数库的.C#把访问数据库这一部分的知识点叫作ADO.NET.即是JAVA常常讲到的JDBC这一部分 ...

  8. Alg-4:算法可视化tiny库的实现

    好吧,准备好好实践一下<算法>这本书的内容的,有点讨厌的是这本书是以Java作为示例语言的(好吧,我承认我有语言偏见,Java就是臭).其中有一个Std库,其中涉及到简化输入输出.随机数生 ...

  9. Xenocode Postbuild 2010 for .NET 使用说明

    文章转载自网络 用法一: .导入要加密的dotNET程序或assembly文件(.dll/.exe) .选择第二个选项卡“Protect” .点击“Select Pattern” .选中所有“Obje ...

  10. ASP.NET5,MVC 6,Beta 7与VS 2015 RTM的兼容问题

    温馨提示:本文杂而乱,最终不知所云. Visual Studio 2015 RTM已经于2015年7月20号正式发布,我也在第一时间下载安装了起来. 虽然在5月份就开始使用RC版本,但是还是很期待正式 ...