C#推送信息到APNs的方法
作者:chenzym 发布时间:2023-05-29 05:20:59
标签:C#,信息
本文实例讲述了C#推送信息到APNs的方法。分享给大家供大家参考。具体实现方法如下:
class Program
{
public static DateTime? Expiration { get; set; }
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(), false, new 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;
}
}
希望本文所述对大家的C#程序设计有所帮助。


猜你喜欢
- 目录为什么要实现调用链跟踪?如何实现?第一步,看图、看场景,用户浏览器的一次请求行为所走的路径是什么样的第二步,实现。不想看代码可直接拉最后
- 介绍Java中介者模式(Mediator Pattern)是一种行为设计模式,它可以降低多个对象之间的耦合性,通过一个中介者对象来协调这些对
- 概念:有enum关键字修饰的类,成为枚举类1、枚举规则枚举类的对象可以有类里面定义,不支持重新new出来,枚举类有构造函数,其他的类都一样,
- 1.使用WIFI首先设置用户权限<uses-permission android:name="android.permiss
- 1.前言对于一个Android开发者来说,每一个页面都继承一个单独的系统Activity,有时候会带来很多不必要的困扰。比如:每一个页面会有
- BroadcastReceiver(广播 * )是Android中的四大组件之一。下面就具体介绍一下Broadcast Receiver组件
- 前言:自定义View可以分为两种方式:第一种通过继承ViewGroup,内部通过addView的方式将其他的View组合到一起。第二种则是通
- 本文实例为大家分享了Android简单实现文件下载的具体代码,供大家参考,具体内容如下权限<!-- 文件读写权限 &nbs
- 本文是利用ZXing.Net在WinForm中生成条形码,二维码的小例子,仅供学习分享使用,如有不足之处,还请指正。什么是ZXing.Net
- 项目中需要对一个点击事件进行下载操作,同时通过点击事件,已经可以从jsp页面获取到需要访问的URL和下载的文件名(数据库获取,jsp页面显示
- 引言委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易。它们就
- LRU缓存替换策略缓存是一种非常常见的设计,通过将数据缓存到访问速度更快的存储设备中,来提高数据的访问速度,如内存、CPU缓存、硬盘缓存等。
- 我计划在后续的一段时间内,写一系列关于java 9的文章,虽然java 9 不像Java 8或者Java 11那样的核心java版本,但是还
- 复合语句Java的复合语句是以整个区块为单位的语句,由{}以及{}内包含的内容组成对于复合语句来说,复合语句创建了一个局部变量的作用域,该作
- 一、搭建步骤1、导入jar包、创建项目包结构2、在web.xml中配置前端控制器3、编写springMvc核心配置文件4、编写pojo类和C
- 多数据源的目的在于一个代码模块可调用多个数据库的数据进行某些业务操作。MyBatis-Plus开发者写了一个多数据源叫dynamic-dat
- 先看一下效果图Tinker已知问题由于原理与系统限制,Tinker有以下已知问题:Tinker不支持修改AndroidManifest.xm
- 反射反射定义对象可以通过反射获取他的类,类可以通过反射拿到所有⽅法(包括私有) 通过java语言中的反射机制可以操作字节码文件,可以读和修改
- 数字可以标志货币、百分比、积分和电话号码等,就货币而言,在不同的国家会以不同的格式来定义,本实例将接收用户输入的数字,然后在控制台中输出其货
- this:this理解为:当前对象 或 当前正在创建的对象可以调用的结构:属性、方法;构造器this调用属性、方法:先了解一下形参:形参的意