当前位置: 首页 > news >正文

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);
	});
}


相关文章:

  • 创建Azure Function
  • 金旭亮博客之“桌面应用程序开发技术”资源主页
  • Javascript MV framework 对比
  • 基于LWUIT实现全局按键控制(快捷键)
  • azure 架构选择
  • Swift 3 点击屏幕任意位置隐藏键盘
  • 成为优秀的程序员真不简单
  • Swift 保存pdf并在webview显示
  • jQuery:收集一些基于jQuery框架开发的控件/jquery插件。(1)
  • Swift显示alert和promp confirmation
  • Winforms: 为什么Graphics.DpiX/DpiY总是返回96
  • Swift 无操作时自动登出
  • SQL 死锁进程查看与处理
  • SQL Server进程阻塞的检查和解决办法
  • Azure 软件架构选择
  • php中curl和soap方式请求服务超时问题
  • react-native 安卓真机环境搭建
  • 讲清楚之javascript作用域
  • 你真的知道 == 和 equals 的区别吗?
  • 盘点那些不知名却常用的 Git 操作
  • 使用阿里云发布分布式网站,开发时候应该注意什么?
  • 算法系列——算法入门之递归分而治之思想的实现
  • 译自由幺半群
  • # 日期待t_最值得等的SUV奥迪Q9:空间比MPV还大,或搭4.0T,香
  • (07)Hive——窗口函数详解
  • (10)STL算法之搜索(二) 二分查找
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (27)4.8 习题课
  • (更新)A股上市公司华证ESG评级得分稳健性校验ESG得分年均值中位数(2009-2023年.12)
  • (转)IOS中获取各种文件的目录路径的方法
  • (转)Oracle 9i 数据库设计指引全集(1)
  • (转)利用ant在Mac 下自动化打包签名Android程序
  • (轉貼) UML中文FAQ (OO) (UML)
  • **Java有哪些悲观锁的实现_乐观锁、悲观锁、Redis分布式锁和Zookeeper分布式锁的实现以及流程原理...
  • *p=a是把a的值赋给p,p=a是把a的地址赋给p。
  • .class文件转换.java_从一个class文件深入理解Java字节码结构
  • .htaccess配置重写url引擎
  • .NET 6 在已知拓扑路径的情况下使用 Dijkstra,A*算法搜索最短路径
  • .NET Entity FrameWork 总结 ,在项目中用处个人感觉不大。适合初级用用,不涉及到与数据库通信。
  • .NET 中 GetProcess 相关方法的性能
  • .NET构架之我见
  • .pyc文件还原.py文件_Python什么情况下会生成pyc文件?
  • @Transactional 详解
  • []使用 Tortoise SVN 创建 Externals 外部引用目录
  • [APUE]进程关系(下)
  • [BZOJ4010]菜肴制作
  • [BZOJ4566][HAOI2016]找相同字符(SAM)
  • [C#]扩展方法
  • [codevs 1288] 埃及分数 [IDdfs 迭代加深搜索 ]
  • [CUDA手搓]从零开始用C++ CUDA搭建一个卷积神经网络(LeNet),了解神经网络各个层背后算法原理
  • [Google Guava] 1.1-使用和避免null
  • [INSTALL_FAILED_TEST_ONLY],Android开发出现应用未安装
  • [LeetCode系列]子集枚举问题[无重复元素]
  • [Linux_IMX6ULL驱动开发]-基础驱动
  • [Operating System] {ud923} P4L4: Datacenter Technologies