APNS IOS 消息推送处理失效的Token
在开发苹果推送服务时候,要合理的控制ios设备的Token,而这个Token是由苹果服务器Apns产生的,就是每次app问Apns要Token,由苹果服务器产生的Token会记录到Apns里面,我们需要根据该Token进行制定设备的消息推送,所有Token需要我们自己去记录和管理,每个设备对应唯一的Token,而app的用户登录会有自己约束的别名,与该tokne进行关系绑定,这样按该别名进行推送,就可以找到对应的Token,进而推送到该iso设备上,对应失效的Token我们需要访问苹果的feedbackServer,拿取失效的Token,然后把本地记录的失效token进行移除。
注意事项:
1.建议和feedback服务器建立长连接,连接过于频繁有可能被当做攻击(简简单单的做一些测试时没有关系的);所有在实际开发完成后,我们基本上可以半天与feedback服务器建立一次socket连接,拿取失效的token,
2.获取的token是在上次你给你的应用发推送失败时加feedback服务的,里面会返回失败的具体时间.
3.返回的数据由三部分组成,请看下面的图:

构中包含三个部分,第一部分是一个上次发推送失败的时间戳,第二个部分是device_token的长度,第三部分就是失效的device_token
/// <summary>
/// FeedbackService
/// </summary>
public class FeedbackService
{
public FeedbackService(ApnsConfiguration configuration)
{
Configuration = configuration;
} public ApnsConfiguration Configuration { get; private set; } public delegate void FeedbackReceivedDelegate(string deviceToken, DateTime timestamp);
public event FeedbackReceivedDelegate FeedbackReceived; public void Check()
{
var encoding = Encoding.ASCII; var certificate = Configuration.Certificate; var certificates = new X509CertificateCollection();
certificates.Add(certificate); var client = new TcpClient(Configuration.FeedbackHost, Configuration.FeedbackPort); var stream = new SslStream(client.GetStream(), true,
(sender, cert, chain, sslErrs) => { return true; },
(sender, targetHost, localCerts, remoteCert, acceptableIssuers) => { return certificate; }); stream.AuthenticateAsClient(Configuration.FeedbackHost, certificates, System.Security.Authentication.SslProtocols.Tls, false); //Set up
byte[] buffer = new byte[];
int recd = ;
var data = new List<byte>(); //Get the first feedback
recd = stream.Read(buffer, , buffer.Length); //Continue while we have results and are not disposing
while (recd > )
{
// Add the received data to a list buffer to work with (easier to manipulate)
for (int i = ; i < recd; i++)
data.Add(buffer[i]); //Process each complete notification "packet" available in the buffer
while (data.Count >= ( + + )) // Minimum size for a valid packet
{
var secondsBuffer = data.GetRange(, ).ToArray();
var tokenLengthBuffer = data.GetRange(, ).ToArray(); // Get our seconds since epoch
// Check endianness and reverse if needed
if (BitConverter.IsLittleEndian)
Array.Reverse(secondsBuffer);
var seconds = BitConverter.ToInt32(secondsBuffer, ); //Add seconds since 1970 to that date, in UTC
var timestamp = new DateTime(, , , , , , DateTimeKind.Utc).AddSeconds(seconds); //flag to allow feedback times in UTC or local, but default is local
if (!Configuration.FeedbackTimeIsUTC)
timestamp = timestamp.ToLocalTime(); if (BitConverter.IsLittleEndian)
Array.Reverse(tokenLengthBuffer);
var tokenLength = BitConverter.ToInt16(tokenLengthBuffer, ); if (data.Count >= + + tokenLength)
{ var tokenBuffer = data.GetRange(, tokenLength).ToArray();
// Strings shouldn't care about endian-ness... this shouldn't be reversed
//if (BitConverter.IsLittleEndian)
// Array.Reverse (tokenBuffer);
var token = BitConverter.ToString(tokenBuffer).Replace("-", "").ToLower().Trim(); // Remove what we parsed from the buffer
data.RemoveRange(, + + tokenLength); // Raise the event to the consumer
var evt = FeedbackReceived;
if (evt != null)
evt(token, timestamp);
}
else
{
continue;
} } //Read the next feedback
recd = stream.Read(buffer, , buffer.Length);
} try
{
stream.Close();
stream.Dispose();
}
catch { } try
{
client.Client.Shutdown(SocketShutdown.Both);
client.Client.Dispose();
}
catch { } try { client.Close(); }
catch { }
}
}
下面是处理逻辑:
/// <summary>
/// 处理失效的Token逻辑信息
/// </summary>
public class TokenProvider
{
private FeedbackService fs = null;
private int hour = ;
private string CID; public TokenProvider(ApnsConfiguration cf, string CID)
{
this.fs = fs = new FeedbackService(cf);
this.CID = CID;
try
{
int hour = int.Parse(ConfigurationManager.AppSettings["ManagerTokenHour"]);//Token的控制时间
}
catch { hour = ; }
} /// <summary>
/// 开启处理失效的Token逻辑信息
/// </summary>
/// <param name="cf"></param>
public void Init()
{
try
{
Thread thsub = new Thread(new ThreadStart(() =>
{
while (true)
{
try
{
fs.Check();
}
catch (Exception ex)
{
LogInfoProvider.config.Logs.Add(new LogClass() { LogStr = " fs.Check() Error! CID=" + CID, ExInfo = ex });
}
Thread.Sleep(hour * * * );
}
}));
fs.FeedbackReceived += fs_FeedbackReceived;
thsub.Start();
LogInfoProvider.config.Logs.Add(new LogClass() { LogStr = "Open TokenProvider! CID=" + CID });
}
catch (Exception ex)
{ LogInfoProvider.config.Logs.Add(new LogClass() { LogStr = " Open TokenProvider Error! CID=" + CID, ExInfo = ex }); }
} /// <summary>
/// 处理失效的Token信息
/// </summary>
/// <param name="deviceToken"></param>
/// <param name="timestamp"></param>
private void fs_FeedbackReceived(string deviceToken, DateTime timestamp)
{
try
{
p_DeleteToken p = new p_DeleteToken(deviceToken);
if (p.ExecutionDelete()) {
LogInfoProvider.config.Logs.Add(new LogClass() { LogStr = "Delete lose token success >> " + deviceToken });
} else {
LogInfoProvider.config.Logs.Add(new LogClass() { LogStr = "Delete lose token error >> " + deviceToken, ExInfo = null });
};
}
catch (Exception ex)
{
LogInfoProvider.config.Logs.Add(new LogClass() { LogStr = "fs_FeedbackReceived Error! CID=" + CID, ExInfo = ex });
}
}
}
APNS IOS 消息推送处理失效的Token的更多相关文章
- APNS IOS 消息推送
一.Apns简介: Apns是苹果推送通知服务. 二.原理: APNs会对用户进行物理连接认证,和设备令牌认证(简言之就是苹果的服务器检查设备里的证书以确定其为苹果设备):然后,将服务器的信息接收并且 ...
- APNS IOS 消息推送沙盒模式和发布模式
在做.NET向IOS设备的App进行消息推送时候,采用的是PushSharp开源类库进行消息的推送,而在开发过程中,采用的是测试版本的app,使用的是测试的p12证书采用的是ApnsConfigura ...
- APNS IOS 消息推送JSON格式介绍
在开发向苹果Apns推送消息服务功能,我们需要根据Apns接受的数据格式进行推送.下面积累了我在进行apns推送时候总结的 apns服务接受的Json数据格式 示例 1: 以下负载包含哦一个简单的 a ...
- iOS 消息推送(APNs) 傻瓜式教程
也可以去我的简书页面查看这篇文章 首先: 1.做iOS消息推送需要真机测试 2.做iOS消息推送需要有付费的开发者账号 是否继续看帖? 先学习一下相关的知识吧! 因为中途可能会遇到一些问题,这篇文章或 ...
- Ios 消息推送
手把手教你做iOS推送 http://www.cocoachina.com/industry/20130321/5862.html http://www.cnblogs.com/cdts_change ...
- .NET向APNS苹果消息推送通知
一.Apns简介: Apns是苹果推送通知服务. 二.原理: APNs会对用户进行物理连接认证,和设备令牌认证(简言之就是苹果的服务器检查设备里的证书以确定其为苹果设备):然后,将服务器的信息接收并且 ...
- ios 消息推送流程 转载
iOS开发:推送通知简述及开发实践热度 1已有 706 次阅读 2013-10-15 09:23 |个人分类:经验之谈|系统分类:ios| IOS, 推送一.关于推送通知 推送通知,也被叫做远程通知, ...
- (转)iOS消息推送机制的实现
原:http://www.cnblogs.com/qq78292959/archive/2012/07/16/2593651.html iOS消息推送机制的实现 iOS消息推送的工作机制可以简单的用下 ...
- 【iOS】iOS消息推送机制的实现
iOS消息推送的工作机制可以简单的用下图来概括: Provider是指某个iPhone软件的Push服务器,APNS是Apple Push Notification Service的缩写,是苹果的服务 ...
随机推荐
- Duilib第一步(II)-Hello World
My first Duilib program 1. Prepare for development 打开DuiFarm项目DuiFarm.cpp文件,将除_tWinMain函数之外所有内容删除.删除 ...
- MySQL 之 视图、触发器、存储过程、函数、事物与数据库锁
浏览目录: 1.视图 2.触发器 3.存储过程 4.函数 5.事物 6.数据库锁 7.数据库备份 1.视图 视图:是一个虚拟表,其内容由查询定义.同真实的表一样,视图包含一系列带有名称的列和行数据 视 ...
- pep 8 规范的一些记录
一.pep8起源 龟叔创立Python的初衷里就有创立一个容易阅读的编程语言,所以亲自操刀写了pep8 代码规范,每个项目开始前都要有一个共识,就是自己的代码规范,pep8 就是一个很好的范本. 二. ...
- 吾八哥学Selenium(一):Python下的selenium安装
selenium简介 Selenium也是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包括IE.Mozilla Firefox.Mo ...
- DataTable筛选某列最大值
dt.Compute("max(列名)",""); Compute函数的参数就两个:Expression,和Filter. Expresstion是计算表达式, ...
- mysql 主从同步 mysql代理服务器
搭建mysql主从同步(实现数据自动备份)实例:把主机192.168.4.100的数据库配置为主机192.168.4.99的从数据库 主数据库服务器配置修改配置文件: [root@mysql ~]# ...
- 使用static与const关键字时需要掌握的知识
static:1.不考虑类,static的作用: 1)第一个作用:隐藏.使得全局变量和函数对其它文件不可见,同时避免了不同文件的命名冲突. 2)第二个作用:默认初始化为0.未初始化的全局静 ...
- VxWorks操作系统shell命令与调试方法总结
VxWorks下的调试手段 主要介绍在Tornado集成开发环境下的调试方法,和利用支撑定位问题的步骤.思路. 1 Tornado的调试工具 嵌入式实时操作系统VxWorks和集成开发 ...
- Docker 小记 — Compose & Swarm
前言 任何相对完整的应用服务都不可能是由单一的程序来完成支持,计划使用 Docker 来部署的服务更是如此.大型服务需要进行拆分,形成微服务集群方能增强其稳定性和可维护性.本篇随笔将对 Docker ...
- CF368 D - Persistent Bookcase
re了20多发 还是我在测试数据上操作最后了10多发才发现的 其实只需要多加一句就好了 真的愚蠢啊,要不都能进前100了 #include<bits/stdc++.h> using nam ...