在开发苹果推送服务时候,要合理的控制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的更多相关文章

  1. APNS IOS 消息推送

    一.Apns简介: Apns是苹果推送通知服务. 二.原理: APNs会对用户进行物理连接认证,和设备令牌认证(简言之就是苹果的服务器检查设备里的证书以确定其为苹果设备):然后,将服务器的信息接收并且 ...

  2. APNS IOS 消息推送沙盒模式和发布模式

    在做.NET向IOS设备的App进行消息推送时候,采用的是PushSharp开源类库进行消息的推送,而在开发过程中,采用的是测试版本的app,使用的是测试的p12证书采用的是ApnsConfigura ...

  3. APNS IOS 消息推送JSON格式介绍

    在开发向苹果Apns推送消息服务功能,我们需要根据Apns接受的数据格式进行推送.下面积累了我在进行apns推送时候总结的 apns服务接受的Json数据格式 示例 1: 以下负载包含哦一个简单的 a ...

  4. iOS 消息推送(APNs) 傻瓜式教程

    也可以去我的简书页面查看这篇文章 首先: 1.做iOS消息推送需要真机测试 2.做iOS消息推送需要有付费的开发者账号 是否继续看帖? 先学习一下相关的知识吧! 因为中途可能会遇到一些问题,这篇文章或 ...

  5. Ios 消息推送

    手把手教你做iOS推送 http://www.cocoachina.com/industry/20130321/5862.html http://www.cnblogs.com/cdts_change ...

  6. .NET向APNS苹果消息推送通知

    一.Apns简介: Apns是苹果推送通知服务. 二.原理: APNs会对用户进行物理连接认证,和设备令牌认证(简言之就是苹果的服务器检查设备里的证书以确定其为苹果设备):然后,将服务器的信息接收并且 ...

  7. ios 消息推送流程 转载

    iOS开发:推送通知简述及开发实践热度 1已有 706 次阅读 2013-10-15 09:23 |个人分类:经验之谈|系统分类:ios| IOS, 推送一.关于推送通知 推送通知,也被叫做远程通知, ...

  8. (转)iOS消息推送机制的实现

    原:http://www.cnblogs.com/qq78292959/archive/2012/07/16/2593651.html iOS消息推送机制的实现 iOS消息推送的工作机制可以简单的用下 ...

  9. 【iOS】iOS消息推送机制的实现

    iOS消息推送的工作机制可以简单的用下图来概括: Provider是指某个iPhone软件的Push服务器,APNS是Apple Push Notification Service的缩写,是苹果的服务 ...

随机推荐

  1. IM开发基础知识补课:正确理解前置HTTP SSO单点登陆接口的原理

    1.前言 一个安全的信息系统,合法身份检查是必须环节.尤其IM这种以“人”为中心的社交体系,身份认证更是必不可少. 一些PC时代小型IM系统中,身份认证可能直接做到长连接中(也就是整个IM系统都是以长 ...

  2. SQL替换语句 批量修改、增加、删除字段内容

    sql替换语句,用该命令可以整批替换某字段的内容,也可以批量在原字段内容上加上或去掉字符. 命令总解:update 表的名称 set 此表要替换的字段名=REPLACE(此表要替换的字段名, '原来内 ...

  3. 《android开发艺术探索》读书笔记(十五)--Android性能优化

    接上篇<android开发艺术探索>读书笔记(十四)--JNI和NDK编程 No1: 如果<include>制定了这个id属性,同时被包含的布局文件的根元素也制定了id属性,那 ...

  4. HDU - 1850 Nim博弈

    思路:可以对任意一堆牌进行操作,根据Nim博弈定理--所有堆的数量异或值为0就是P态,否则为N态,那么直接对某堆牌操作能让所有牌异或值为0即可,首先求得所有牌堆的异或值,然后枚举每一堆,用已经得到的异 ...

  5. UVA-11214 IDA*

    利用迭代加深搜索,枚举需要的皇后数量,进行搜索. 对于10 * 10 的棋盘,最多需要5个皇后就能攻击整个棋盘,当0~4个皇后都不能搜索成功,那么5就不用搜索,直接打印. AC代码: #include ...

  6. php-fpm问题

    这个问题怎么说呢?之前遇到这个问题内心是奔溃的.因为我压根不知道是哪里出问题啦.不过,在我努力探索下,最终还是解决了问题. so请记住,坚持不一定成功,但放弃一定失败. 简单描述一下问题: 1.本地的 ...

  7. java 集合框架(一)概述

    一.概述 Java Collection Framework (JCF) 提供给我们一系列的类和接口,方便开发者处理集合对象. 在Java 2之前,Java是没有完整的集合框架的.它只有一些简单的可以 ...

  8. HighGUI图形图像界面初步—— 图像的载入、显示与输出

    HighGUI模块为高层GUI图形用户界面模块,包含媒体的输入输出.视频捕捉.图像和视频的编解码.图形交互界面的接口等. 在本章中,我们将学到: 图像的载入.显示和输出到文件的详细分析 滑动条的创建和 ...

  9. MySQL Crash Errcode: 28 - No space left on device

    一台MySQL服务器突然Crash了,检查进程 ps -ef | grep -i mysql 发现mysqld进程已经没有了, 检查错误日志时发现MySQL确实Crash了.具体如下所示: 注意日志中 ...

  10. SQL中partition关键字的使用

    最近在写后台语句时候,运用到了partition这样一个关键字. 先大致说一下背景,有一种数据表,如下 现在需要取出,每一个人最近的一次打卡时间. 思路是,先把数据按照人名分组,然后在每个组里面按照时 ...