从苹果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#.Net 上传图片,限制图片大小,检查类型完整版
C#.Net 上传图片,限制图片大小,检查类型完整版 源代码: 处理图片类,如检查图片大小,按宽度比例缩小图片 public class CImageLibrary{ public enum Va ...
- Source Insight 使用
1.括号配对高亮:“在前括号左侧,后括号左侧” 双击鼠标左键,可以选定匹配括号和其中内容(<>,(),L{R},[]之间) 2.让{ 和 } 不缩进:Options -> Docum ...
- 通过PowerShell获取Windows系统密码Hash
当你拿到了系统控制权之后如何才能更长的时间内控制已经拿到这台机器呢?作为白帽子,已经在对手防线上撕开一个口子,如果你需要进一步扩大战果,你首先需要做的就是潜伏下来,收集更多的信息便于你判断,便于有更大 ...
- sql 字符次数
FParentPath 查询字段 本条语句 条件是 , 查询 , 在这个字段出现了几次 1=没有 2=1次 3=2次(依次累加)
- ubuntu下 mysql5.6.4 +sphinx安装
安装mysql 5.6.4 下载源码 安装cmake sudo apt-get install cmake 进入mysql源码包: 创建mysql用户与用户组 groupadd mysql usera ...
- C# Json帮助类
using System; using System.Collections.Generic; using System.Web; using System.Text; using System.Re ...
- eclipse 编译出错(java.io.ObjectInputStream)的解决办法
Multiple markers at this line - The type java.io.ObjectInputStream cannot be resolved. It is indirec ...
- 关于Linux session管理与GUI架构
google了一下感觉一下子找不到太好的资料,可能需要慢慢深入去学习. 这里有一个讲session management的,还算比较深入: https://dvdhrm.wordpress.com/2 ...
- C#基础课程之五集合(HashTable,Dictionary)
HashTable例子: #region HashTable #region Add Hashtable hashTable = new Hashtable(); Hashtable hashTabl ...
- poj 1474 Video Surveillance - 求多边形有没有核
/* poj 1474 Video Surveillance - 求多边形有没有核 */ #include <stdio.h> #include<math.h> const d ...