Iphone 消息通知(APNS)的3种方式 -- C# 和 nodejs
发送 APNS 使用 p12 文件(C#)
public static bool PushWithP12(string apnToken, string message)
{
_log.DebugFormat("[Apns] step 1");
_log.DebugFormat("Token = " + apnToken);
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;
// var file = File.ReadAllBytes(ConfigurationManager.AppSettings["ApnsCertificate"]);
var config = new ApnsConfiguration(ApnsConfiguration.ApnsServerEnvironment.Sandbox, ConfigurationManager.AppSettings["ApnsCertificate"], ConfigurationManager.AppSettings["ApnsPassword"]);
// Create a new broker
var apnsBroker = new ApnsServiceBroker(config);
_log.DebugFormat("[Apns] step 2");
// Wire up events
apnsBroker.OnNotificationFailed += (notification, aggregateEx) =>
{
_log.DebugFormat("[Apns] step 3");
aggregateEx.Handle(ex =>
{
_log.DebugFormat("[Apns] step 4");
// See what kind of exception it was to further diagnose
if (ex is ApnsNotificationException)
{
_log.DebugFormat("[Apns] step 5");
var notificationException = (ApnsNotificationException)ex;
_log.DebugFormat("[Apns] step 6");
// Deal with the failed notification
var apnsNotification = notificationException.Notification;
var statusCode = notificationException.ErrorStatusCode;
_log.ErrorFormat($"Apple Notification Failed: ID={apnsNotification.Identifier}, Code={statusCode}");
return false;
}
else
{
// Inner exception might hold more useful information like an ApnsConnectionException
_log.ErrorFormat($"Apple Notification Failed for some unknown reason : {ex.InnerException}");
return false;
}
// Mark it as handled
//return true;
});
};
_log.DebugFormat("[Apns] step 7");
apnsBroker.OnNotificationSucceeded += (notification) =>
{
_log.InfoFormat("Apple Notification Sent!");
};
_log.DebugFormat("[Apns] step 8");
// Start the broker
apnsBroker.Start();
_log.DebugFormat("[Apns] step 9");
// Queue a notification to send
var apnsObj = new PayLoadEntity()
{
aps = new Aps()
{
alert = message
}
};
var apnsStr = JsonConvert.SerializeObject(apnsObj);
_log.DebugFormat("[Apns] step 9.1");
_log.DebugFormat(apnsStr);
apnsBroker.QueueNotification(new ApnsNotification
{
DeviceToken = apnToken,
Payload = JObject.Parse(apnsStr)
});
_log.DebugFormat("[Apns] step 10");
// Stop the broker, wait for it to finish
// This isn't done after every message, but after you're
// done with the broker
apnsBroker.Stop();
_log.DebugFormat("[Apns] step 11");
return true;
}
// 发送 APNS 使用 p8 文件(c#)
static async void TokenBasedAuthenticationAPNsPush(string message, string token)
{
string algorithm = "ES256";
string apnsKeyId = "{your_key_id}"; // get from apple dev account
string teamId = "get from your membership info";
string authKeyPath = "apns.p8"; // generate from apple account
string bundleId = "your app id";
string registrationId = token;
var privateKeyContent = System.IO.File.ReadAllText(authKeyPath);
var privateKey = privateKeyContent.Split('\n')[1];
var secretKeyFile = Convert.FromBase64String(privateKey);
var secretKey = CngKey.Import(secretKeyFile, CngKeyBlobFormat.Pkcs8PrivateBlob);
var expiration = DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
var expirationSeconds = (long)expiration.TotalSeconds;
var payload = new Dictionary<string, object>()
{
{ "iss", teamId },
{ "iat", expirationSeconds }
};
var header = new Dictionary<string, object>()
{
{ "alg", algorithm },
{ "kid", apnsKeyId }
};
string accessToken = Jose.JWT.Encode(payload, secretKey, JwsAlgorithm.ES256, header);
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;
//Development server:api.development.push.apple.com:443
//Production server:api.push.apple.com:443
string host = "api.development.push.apple.com";
//string host = "api.push.apple.com";
int port = 443;
// Uri to request
var uri = new Uri(string.Format("https://{0}:{1}/3/device/{2}", host, port, registrationId));
var payloadData = JObject.FromObject(new
{
aps = new
{
alert = message
}
});
byte[] data = System.Text.Encoding.UTF8.GetBytes(payloadData.ToString());
var handler = new Http2MessageHandler();
var httpClient = new HttpClient(handler);
var requestMessage = new HttpRequestMessage();
requestMessage.RequestUri = uri;
requestMessage.Headers.Add("authorization", string.Format("bearer {0}", accessToken));
requestMessage.Headers.Add("apns-id", Guid.NewGuid().ToString());
requestMessage.Headers.Add("apns-expiration", "0");
requestMessage.Headers.Add("apns-priority", "10");
requestMessage.Headers.Add("apns-topic", bundleId);
requestMessage.Method = HttpMethod.Post;
requestMessage.Content = new ByteArrayContent(data);
try
{
var responseMessage = await httpClient.SendAsync(requestMessage);
if (responseMessage.StatusCode == System.Net.HttpStatusCode.OK)
{
string responseUuid = string.Empty;
IEnumerable<string> values;
if (responseMessage.Headers.TryGetValues("apns-id", out values))
{
responseUuid = values.First();
}
Console.WriteLine(string.Format("\n\r*******Send Success [{0}]", responseUuid));
}
else
{
var body = await responseMessage.Content.ReadAsStringAsync();
var json = new JObject();
json = JObject.Parse(body);
var reasonStr = json.Value<string>("reason");
Console.WriteLine("\n\r*******Failure reason => " + reasonStr);
}
Console.ReadKey();
}
catch (Exception ex)
{
var info = "";
DumpAllInfoOfException(ex, ref info);
Console.WriteLine("\n\r*******Exception message => " + ex.Message);
Console.WriteLine(info);
}
}
下面这种方式是NODEJS+p8文件实现的
function Send_APNS(param_msg, param_device){
var apn = require('apn');
// Set up apn with the APNs Auth Key
var apnProvider = new apn.Provider({
token: {
key: 'apns.p8', // Path to the key p8 file
keyId: 'xxx', // The Key ID of the p8 file (available at https://developer.apple.com/account/ios/certificate/key)
teamId: 'xxxx', // The Team ID of your Apple Developer Account (available at https://developer.apple.com/account/#/membership/)
},
production: false // Set to true if sending a notification to a production iOS app
});
// Enter the device token from the Xcode console
var deviceToken = param_device;
// Prepare a new notification
var notification = new apn.Notification();
// Specify your iOS app's Bundle ID (accessible within the project editor)
notification.topic = 'nec.com.sg.BCMS';
// Set expiration to 1 hour from now (in case device is offline)
notification.expiry = Math.floor(Date.now() / 1000) + 3600;
// Set app badge indicator
notification.badge = 3;
// Play ping.aiff sound when the notification is received
notification.sound = 'ping.aiff';
// Display the following message (the actual notification text, supports emoji)
notification.alert = param_msg;
// Send any extra payload data with the notification which will be accessible to your app in didReceiveRemoteNotification
notification.payload = {id: 1};
// Actually send the notification
apnProvider.send(notification, deviceToken).then(function(result) {
// Check the result for any failed devices
console.log(result);
});
}
Iphone 消息通知(APNS)的3种方式 -- C# 和 nodejs的更多相关文章
- 聊聊业务系统中投递消息到mq的几种方式
背景 电商中有这样的一个场景: 下单成功之后送积分的操作,我们使用mq来实现 下单成功之后,投递一条消息到mq,积分系统消费消息,给用户增加积分 我们主要讨论一下,下单及投递消息到mq的操作,如何实现 ...
- 聊聊mq中消息消费的几种方式
mq系列文章 对mq了解不是很多的,可以看一下下面两篇文章: 聊聊mq的使用场景 聊聊业务系统中投递消息到mq的几种方式 聊聊消息消费的几种方式 如何确保消息至少消费一次 如何保证消息消费的幂等性 本 ...
- 源码详解openfire保存消息记录_修改服务端方式
实现openfire消息记录通常有两种方式,修改服务端和添加消息记录插件. 今天,简单的说明一下修改服务端方式实现消息记录保存功能. 实现思路 修改前: 默认的,openfire只提供保存离线记录至o ...
- WINDOWS硬件通知应用程序的常方法(五种方式:异步过程调用APC,事件方式VxD,消息方式,异步I/O方式,事件方式WDM)
摘要:在目前流行的Windows操作系统中,设备驱动程序是操纵硬件的最底层软件接口.为了共享在设备驱动程序设计过程中的经验,给出设备驱动程序通知应用程序的5种方法,详细说明每种方法的原理和实现过程,并 ...
- RocketMQ(6)---发送普通消息(三种方式)
发送普通消息(三种方式) RocketMQ 发送普通消息有三种实现方式:可靠同步发送.可靠异步发送.单向(Oneway)发送. 注意 :顺序消息只支持可靠同步发送. GitHub地址: https:/ ...
- 横竖屏事件响应(viewWillLayoutSubviews和通知)两种方式
转载:http://blog.csdn.net/nogodoss/article/details/17246489 最近搞横竖屏,获得一些心得,特记录下来. 做横竖屏最重要的是确定横竖屏响应的接口.目 ...
- ActiveMQ持久化消息的三种方式
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt362 本文只介绍三种方式,分别是持久化为文件,MYSql,Oracle.下面 ...
- Kafka生产者发送消息的三种方式
Kafka是一种分布式的基于发布/订阅的消息系统,它的高吞吐量.灵活的offset是其它消息系统所没有的. Kafka发送消息主要有三种方式: 1.发送并忘记 2.同步发送 3.异步发送+回调函数 下 ...
- ios消息队列APNS实现和证书申请
iOS消息推送的工作机制可以简单的用下图来概括: Provider是指某个iPhone软件的Push服务器,APNS是Apple Push Notification Service的缩写,是苹果的服务 ...
随机推荐
- 20145328 《Java程序设计》实验五实验报告
20145328 <Java程序设计>实验五实验报告 实验名称 Java网络编程 实验内容 用书上的TCP代码,实现服务器与客户端. 客户端与服务器连接 客户端中输入明文,利用DES算法加 ...
- linux中断的下半部机制
一.中断处理为什么要下半部?Linux在中断处理中间中断处理分了上半部和下半部,目的就是提高系统的响应能力和并发能力.通俗一点来讲:当一个中断产生,调用该中断对应的处理程序(上半部)然后告诉系统,对应 ...
- unicode下数据之间的转换
首先mfc下字符串只有两种数据:char(一个字节)和wchar_t(两个字节),很多其他数据类型如TCHAR,WCHAR等都是这个两个基本类型的宏定义,BYTE是uchar 1.对话框打印char* ...
- 4.9版本的linux内核中温度传感器adt7461的驱动源码在哪里
答:drivers/hwmon/lm90.c,这个文件中支持了好多芯片,内核配置项为CONFIG_SENSORS_LM90 Location: -> Device Drivers -> H ...
- erwin逆向工程,logical模型列名修改为中文
逆向工程,应该选择physical template,这样拷贝到logical/physical 模型中,才可以将logical模型的列名修改为中文.
- 【cs231n】线性分类笔记
前言 首先声明,以下内容绝大部分转自知乎智能单元,他们将官方学习笔记进行了很专业的翻译,在此我会直接copy他们翻译的笔记,有些地方会用红字写自己的笔记,本文只是作为自己的学习笔记.本文内容官网链接: ...
- Pandas 高级应用 数据分析
深入pandas 数据处理 三个阶段 数据准备 数据转化 数据聚合 数据准备 加载 组装 合并 - pandas.merge() 拼接 - pandas.concat() 组合 - pandas.Da ...
- 关于ckeditor 之 上传功能
度了很多文章,看了很多关于ckeditor配置上传功能的文章,没一个写得清楚的, 就是简单的根目录下.config.js 增加 config.filebrowserUploadUrl="/a ...
- PIL中文文档
(0)http://hereson.iteye.com/blog/2224334 (1)http://blog.csdn.net/yjwx0018/article/details/52852067 ( ...
- Linux命令详解-touch
linux的touch命令不常用,一般在使用make的时候可能会用到,用来修改文件时间戳,或者新建一个不存在的文件. 1.命令格式: touch [选项]... 文件... 2.命令参数: -a 或- ...