从苹果apns的feedback服务器获取推送失败的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
贴下PushSharp中连接feedback的代码
/// <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
];
;
var data = new List<byte>();
//Get the first feedback
recd = stream.Read(buffer, , buffer.Length);
//Continue while we have results and are not disposing
)
{
// Add the received data to a list buffer to work with (easier to manipulate)
; i < recd; i++)
data.Add(buffer[i]);
//Process each complete notification "packet" available in the buffer
+ + )) // Minimum size for a valid packet
{
, ).ToArray();
, ).ToArray();
// Get our seconds since epoch
// Check endianness and reverse if needed
if (BitConverter.IsLittleEndian)
Array.Reverse(secondsBuffer);
);
//Add seconds since 1970 to that date, in UTC
, , , , , , 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);
);
+ + tokenLength)
{
, 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 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的控制时间
}
; }
}
/// <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的feedback服务器获取推送失败的token的更多相关文章
- javascript跨域传递消息 / 服务器实时推送总结
参考文档,下面有转载[非常好的两篇文章]: http://www.cnblogs.com/loveis715/p/4592246.html [跨源的各种方法总结] http://kb.cnblogs. ...
- iOS,APP退到后台,获取推送成功的内容并且语音播报内容。
老铁,我今天忙了一下午就为解决这个问题,网上有一些方法,说了一堆关于这个挂到后台收到推送并且获得推送内容的问题,有很多人都说APP挂到后台一会就被杀死.但实际上可以有办法解决的. WechatIMG3 ...
- php 微信客服信息推送失败 微信重复推送客服消息 40001 45047
/*** * 微信客服发送信息 * 微信客服信息推送失败 微信重复推送客服消息 40001 45047 * 递归提交到微信 直到提交成功 * @param $openid * @param int $ ...
- SignalR SelfHost实时消息,集成到web中,实现服务器消息推送
先前用过两次SignalR,但是中途有段时间没弄了,今天重新弄,发现已经忘得差不多了,做个笔记! 首先创建一个控制台项目Nuget添加引用联机搜索:Microsoft.AspNet.SignalR.S ...
- IOS 在不打开电话服务的时候,可以响应服务器的推送消息,从而接收服务器的推送消息
在做即时通讯(基于xmpp框架)的时候遇到这样一个问题,就是在真机测试的时候,你按Home键返回桌面,在你返回桌面的时候,这是你的程序的挂起状态的,在你挂起的时候, 相当于你的程序是死的,程序的所有进 ...
- 利用nginx_push_stream_module实现服务器消息推送
NGiNX_HTTP_Push_Module 是一个 Nginx 的扩展模块,它实现了 HTTP Push 和Comet server的功能.HTTP Push 被经常用在网页上主动推的技术,例如一些 ...
- [Apple开发者帐户帮助]六、配置应用服务(5.3)推送通知(APN):从您的Web服务器发送推送通知
要使用APN从Web服务器向macOS用户发送推送通知,请注册网站推送标识符并创建网站推送证书. 对于每个网站,请注册一个网站推送标识符,用于验证通知是否来自您的服务器.然后创建一个网站推送证书以签署 ...
- html5:服务器事件推送(server-sent events)Asp.net
支持 不支持IE 个人理解说明 个人理解:这种消息推送方式不太推广,原因有以下三点~~~`我怎么老是学这些自己认为不会推广的东西呢~汗 在.net中,framework4.5以上就可以由SignalR ...
- HTML5服务器消息推送(java版)
前端代码(html5.html): <html> <meta http-equiv="Content-Type" content="text/html; ...
随机推荐
- C++虚函数与虚函数表
多态性可分为两类:静态多态和动态多态.函数重载和运算符重载实现的多态属于静态多态,动态多态性是通过虚函数实现的. 每个含有虚函数的类有一张虚函数表(vtbl),表中每一项是一个虚函数的地址, 也就是说 ...
- 菜鸟类库诞生记二:通过反射转换DataRow为对象
虽然大数据量的环境下,通过反射转换DataRow为对象性能会很低,但是在数据量适中的时候,这样能够减少很多的代码量,性能也确实不错. 所以在数据量不是很大的情况下,推荐使用. 如果数据量很大,可以使用 ...
- Xcode 文档注释方法
摘自:http://www.cnblogs.com/bomo/p/4815963.html 文档注释,可以在调用时显示注释信息,让调用者更好的理解方法的用途. 注释方法: /// 注释 和 /** 注 ...
- HTTP协议学习
面试过程中又一个常见的问题,http协议,因为做服务器开发如果用http协议的话,现在各种开源软件都封装好了,python中只需要简单的继承定义好的类,重写get或者post等方法,几行代码就可以搭建 ...
- Scala spark mongodb
最好的参考是Mongo官网的地址 https://docs.mongodb.com/spark-connector/getting-started/ 需要截图所示的包 代码地址 https://git ...
- EPLAN P8导线颜色的设置
P8里的导线应称为"连接",连接的颜色代表了其电位的传递路径,如可以给三相电源设置成黑色,PE设为绿色,N设为蓝色等等. P8中电位在连接和元器件中传递的方法是由元器件的连接点属 ...
- ext 文档下载地址
ext官方太鬼了,离线文档下载地址藏的太深了,找出来真不容易 http://docs.sencha.com/misc/guides/offline_docs.html
- BZOJ 1006 [HNOI2008] 神奇的国度(简单弦图的染色)
题目大意 K 国是一个热衷三角形的国度,连人的交往也只喜欢三角原则.他们认为三角关系:即 AB 相互认识,BC 相互认识,CA 相互认识,是简洁高效的.为了巩固三角关系,K 国禁止四边关系,五边关系等 ...
- java实现二叉树查找树
二叉树(binary)是一种特殊的树.二叉树的每个节点最多只能有2个子节点: 二叉树 由于二叉树的子节点数目确定,所以可以直接采用上图方式在内存中实现.每个节点有一个左子节点(left childre ...
- REHL5.5 linux的postfix的邮件服务器配置 (笔记)
一.发送邮件服务器(smtp服务器) 1.系统安装时已经有postfix. 2.修改配置 1)vi main.cf //你可以先备份一下配置文件 myhostname = INMSC2//修改为你的主 ...