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

  1. javascript跨域传递消息 / 服务器实时推送总结

    参考文档,下面有转载[非常好的两篇文章]: http://www.cnblogs.com/loveis715/p/4592246.html [跨源的各种方法总结] http://kb.cnblogs. ...

  2. iOS,APP退到后台,获取推送成功的内容并且语音播报内容。

    老铁,我今天忙了一下午就为解决这个问题,网上有一些方法,说了一堆关于这个挂到后台收到推送并且获得推送内容的问题,有很多人都说APP挂到后台一会就被杀死.但实际上可以有办法解决的. WechatIMG3 ...

  3. php 微信客服信息推送失败 微信重复推送客服消息 40001 45047

    /*** * 微信客服发送信息 * 微信客服信息推送失败 微信重复推送客服消息 40001 45047 * 递归提交到微信 直到提交成功 * @param $openid * @param int $ ...

  4. SignalR SelfHost实时消息,集成到web中,实现服务器消息推送

    先前用过两次SignalR,但是中途有段时间没弄了,今天重新弄,发现已经忘得差不多了,做个笔记! 首先创建一个控制台项目Nuget添加引用联机搜索:Microsoft.AspNet.SignalR.S ...

  5. IOS 在不打开电话服务的时候,可以响应服务器的推送消息,从而接收服务器的推送消息

    在做即时通讯(基于xmpp框架)的时候遇到这样一个问题,就是在真机测试的时候,你按Home键返回桌面,在你返回桌面的时候,这是你的程序的挂起状态的,在你挂起的时候, 相当于你的程序是死的,程序的所有进 ...

  6. 利用nginx_push_stream_module实现服务器消息推送

    NGiNX_HTTP_Push_Module 是一个 Nginx 的扩展模块,它实现了 HTTP Push 和Comet server的功能.HTTP Push 被经常用在网页上主动推的技术,例如一些 ...

  7. [Apple开发者帐户帮助]六、配置应用服务(5.3)推送通知(APN):从您的Web服务器发送推送通知

    要使用APN从Web服务器向macOS用户发送推送通知,请注册网站推送标识符并创建网站推送证书. 对于每个网站,请注册一个网站推送标识符,用于验证通知是否来自您的服务器.然后创建一个网站推送证书以签署 ...

  8. html5:服务器事件推送(server-sent events)Asp.net

    支持 不支持IE 个人理解说明 个人理解:这种消息推送方式不太推广,原因有以下三点~~~`我怎么老是学这些自己认为不会推广的东西呢~汗 在.net中,framework4.5以上就可以由SignalR ...

  9. HTML5服务器消息推送(java版)

    前端代码(html5.html): <html> <meta http-equiv="Content-Type" content="text/html; ...

随机推荐

  1. 移植UE4的模型操作到Unity中

    最近在Unity上要写一个东东,功能差不多就是在Unity编辑器上的旋转,移动这些,在手机上也能比较容易操作最好,原来用Axiom3D写过一个类似的,有许多位置并不好用,刚好在研究UE4的源码,在模型 ...

  2. 管理批量邮箱 FOXMAIL 和网易闪电邮(PC端)有什么区别? 对比

    喜欢用FOXMAIL有订阅功能&lt;img src="https://pic1.zhimg.com/fa72df2440f84043a5275b90df30b2f4_b.jpg&q ...

  3. Windows下Git安装指南

    参考<Git权威指南>安装整理,图书配套网址参见[1] 1. Cygwin下安装配置Git 1. 在Windows下安装配置Git有2种不同的方案 (1)msysGit, (2)Cygwi ...

  4. CREATE A LOADING SCENE / SPLASH SCREEN - UNITY

    In the first scene or maybe the Main Menu scene of your game Create an Empty Gameobject. Call it wha ...

  5. 精选19款华丽的HTML5动画和实用案例

    下面是本人收集的19款超酷HTML5动画和实用案例,觉得不错,分享给大家. 1.HTML5 Canvas火焰喷射动画效果 还记得以前分享过的一款HTML5烟花动画HTML5 Canvas烟花特效,今天 ...

  6. Eplan转载

    引言:标准化工程设计理念成功实施后之后,清晰透明的管理流程将水到渠成,过往繁复无比的流程得以简化,管理与被管理者皆愿欣然承受. 市场竞争日趋激烈的今天,对用户需求.市场的快速响应,尽量地控制成本是企业 ...

  7. POJ 3519 Minimal Backgammon

    Minimal Backgammon Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 1195   Accepted: 700 ...

  8. 使用UIKit制作卡牌游戏(三)ios游戏篇

    译者: Lao Jiang | 原文作者: Matthijs Hollemans写于2012/07/13 转自朋友Tommy 的翻译,自己只翻译了这第三篇教程. 原文地址: http://www.ra ...

  9. Mac OS使用ll、la、l等ls的别名命令

    在linux下习惯使用ll.la.l等ls别名的童鞋到mac os可就郁闷了-- 其实只要在用户目录下建立一个脚本“.bash_profile”,并输入以下内容即可: alias ll='ls -al ...

  10. Winform快速开发组件的实现(二)

    昨天我们一直在做准备工作,最终表单数据需要从数据库里提取,并保存到数据库,今天接着介绍如何做提取.保存和验证. 四.提取并显示信息 在EditForm我们定义一个InfoId属性,用于接收在列表页面打 ...