• C# 推送信息到APNs


    iPhone消息推送机制实现与探讨


    class Program
        {
     
            public static DateTime? Expiration { getset; }
     
            public static readonly DateTime DoNotStore = DateTime.MinValue;
            private static readonly DateTime UNIX_EPOCH = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            private static string DeviceToken = "273eeddaef02192cf4ba5b666453b258f2d2a1ad02f549105fd03fea789d809d";
            public const int DEVICE_TOKEN_BINARY_SIZE = 32;
            public const int DEVICE_TOKEN_STRING_SIZE = 64;
            public const int MAX_PAYLOAD_SIZE = 256;
            private static X509Certificate certificate;
            private static X509CertificateCollection certificates;
     
            static void Main(string[] args)
            {
                string hostIP = "gateway.sandbox.push.apple.com";//
                int port = 2195;
                string password = "ankejiaoyu";//
                string certificatepath = "aps_developer_identity.p12";//bin/debug
                string p12Filename = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, certificatepath);
     
     
                certificate = new X509Certificate2(System.IO.File.ReadAllBytes(p12Filename), password, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
     
                certificates = new X509CertificateCollection();
                certificates.Add(certificate);
     
     
                TcpClient apnsClient = new TcpClient();
                apnsClient.Connect(hostIP, port);
     
                SslStream apnsStream = new SslStream(apnsClient.GetStream(), falsenew RemoteCertificateValidationCallback(validateServerCertificate), new LocalCertificateSelectionCallback(selectLocalCertificate));
     
                try
                {
                    //APNs已不支持SSL 3.0 
                    apnsStream.AuthenticateAsClient(hostIP, certificates, System.Security.Authentication.SslProtocols.Tls, false);
                }
                catch (System.Security.Authentication.AuthenticationException ex)
                {
                    Console.WriteLine("error+"+ex.Message);
                }
     
                if (!apnsStream.IsMutuallyAuthenticated)
                {
                    Console.WriteLine("error:Ssl Stream Failed to Authenticate!");
                }
     
                if (!apnsStream.CanWrite)
                {
                    Console.WriteLine("error:Ssl Stream is not Writable!");
                    
                }
     
                Byte[] message = ToBytes();
                apnsStream.Write(message);
            }
     
            public static byte[] ToBytes()
            {
     
                // Without reading the response which would make any identifier useful, it seems silly to
                // expose the value in the object model, although that would be easy enough to do. For
                // now we'll just use zero.
                int identifier = 0;
                byte[] identifierBytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(identifier));
     
                // APNS will not store-and-forward a notification with no expiry, so set it one year in the future
                // if the client does not provide it.
                int expiryTimeStamp = -1;//过期时间戳
                if (Expiration != DoNotStore)
                {
                    //DateTime concreteExpireDateUtc = (Expiration ?? DateTime.UtcNow.AddMonths(1)).ToUniversalTime();
                    DateTime concreteExpireDateUtc = (Expiration ?? DateTime.UtcNow.AddSeconds(20)).ToUniversalTime();
                    TimeSpan epochTimeSpan = concreteExpireDateUtc - UNIX_EPOCH;
                    expiryTimeStamp = (int)epochTimeSpan.TotalSeconds;
                }
     
                byte[] expiry = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(expiryTimeStamp));
     
                byte[] deviceToken = new byte[DeviceToken.Length / 2];
                for (int i = 0; i < deviceToken.Length; i++)
                    deviceToken[i] = byte.Parse(DeviceToken.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber);
     
                if (deviceToken.Length != DEVICE_TOKEN_BINARY_SIZE)
                {
                    Console.WriteLine("Device token length error!");
                }
     
                byte[] deviceTokenSize = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(Convert.ToInt16(deviceToken.Length)));
                string str = "{"aps":{"alert":"这是测试消息!!","badge":1,"sound":"anke.mp3"}}";
     
                byte[] payload = Encoding.UTF8.GetBytes(str);
     
                byte[] payloadSize = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(Convert.ToInt16(payload.Length)));
                List<byte[]> notificationParts = new List<byte[]>();
                //1 Command
                notificationParts.Add(new byte[] { 0x01 }); // Enhanced notification format command
                notificationParts.Add(identifierBytes);
                notificationParts.Add(expiry);
                notificationParts.Add(deviceTokenSize);
                notificationParts.Add(deviceToken);
                notificationParts.Add(payloadSize);
                notificationParts.Add(payload);
     
                return BuildBufferFrom(notificationParts);
            }
     
            private static byte[] BuildBufferFrom(IList<byte[]> bufferParts)
            {
                int bufferSize = 0;
                for (int i = 0; i < bufferParts.Count; i++)
                    bufferSize += bufferParts[i].Length;
     
                byte[] buffer = new byte[bufferSize];
                int position = 0;
                for (int i = 0; i < bufferParts.Count; i++)
                {
                    byte[] part = bufferParts[i];
                    Buffer.BlockCopy(bufferParts[i], 0, buffer, position, part.Length);
                    position += part.Length;
                }
                return buffer;
            }
     
            private static bool validateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
            {
                return true// Dont care about server's cert
            }
     
            private static X509Certificate selectLocalCertificate(object sender, string targetHost, X509CertificateCollection localCertificates,
                X509Certificate remoteCertificate, string[] acceptableIssuers)
            {
                return certificate;
            }

        }

    PS:上面这段代码是从网上找的,做了些小改动。



  • 相关阅读:
    洛谷3004 [USACO10DEC]宝箱Treasure Chest
    洛谷3778 [APIO2017]商旅
    洛谷4141消失之物——每个体积的角度
    洛谷2943 [USACO09MAR]清理Cleaning Up——转变枚举内容的dp
    bzoj1858[Scoi2010]序列操作
    poj1325机器工作——二分图最小点覆盖
    洛谷P1144——最短路计数
    poj3254二进制放牛——状态压缩DP
    poj1191棋盘分割——区间DP
    洛谷P1474货币系统——背包方案计数
  • 原文地址:https://www.cnblogs.com/czblogs/p/4478195.html
Copyright © 2020-2023  润新知