在开发自己的苹果推送服务时候,要合理的控制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. MYSQL校对规则

    一.前言 有时候遇到这种情况,你用一个like语句查询,查到的结果中有一些并没有包含你查询的关键词的纪录:有时候遇到这种情况,你的数据库自作聪明的大小写不敏感,让你在更新时把大小写不同的两条记录都更新 ...

  2. Swift基础--手势识别(双击、捏、旋转、拖动、划动、长按)

    // //  ViewController.swift //  JieUITapGestureRecognizer // //  Created by jiezhang on 14-10-4. //  ...

  3. GPL与LGPL的区别

    GPL(GNU General Public License)  我们很熟悉的Linux就是采用了GPL.GPL协议和BSD, Apache Licence等鼓励代码重用的许可很不一样.GPL的出发点 ...

  4. rbenv Your user account isn't allowed to install to the system Rubygems

    Clone一个新Rails项目到Mac, bundle install 的时候遇到下面的提示 Fetching source index from http://rubygems.org/ Your ...

  5. 本博客停止更新,移至purecpp.org

    声明:本博客停止更新,迁移至C++开源社区purecpp.org, 欢迎持续关注!

  6. LoadRunner场景参数文件部分参数说明(我在某银行的整理)

    由于场景中脚本繁多,同时设置60个脚本的“运行时设置”会提示个数限制信息,这时可以考虑通过场景的参数文件配置来批量解决这些事情,主要是提高工作效率. 选中自己保存的controller场景,鼠标右键点 ...

  7. SAP ECC PP 配置文档

    SAP ECC 6.0 Configuration Document Production Planning & Control (PP) 1. General Settings 1.1 Ma ...

  8. nginx server_name

    在我的机子了nginx的  server_name要配制成127.0.0.1才能用,否则就报错,刚试用nginx还不知道为什么,先记下来

  9. managed_shared_memory.construct造成的性能损失

    boost中的IPC进程间通信非常好用,可以直接在共享内存上创建对象,相当于new分配器,实测发现它的分配算法还是有点耗时.第一个测试代码仅仅分配一次,然后频繁的复制,每秒钟可以复制4200次左右. ...

  10. BZOJ 1006 [HNOI2008] 神奇的国度(简单弦图的染色)

    题目大意 K 国是一个热衷三角形的国度,连人的交往也只喜欢三角原则.他们认为三角关系:即 AB 相互认识,BC 相互认识,CA 相互认识,是简洁高效的.为了巩固三角关系,K 国禁止四边关系,五边关系等 ...