我希望创建APNS(Apple推送通知服务),服务器将向iOS设备发送通知。 我可以使用SAME设备令牌和SAME证书通过PHP进行推送通知,但是,我想通过Node JS而不是PHP发送通知。
我有以下有效的文件/证书来帮助我入门:
我一直在浏览几个资源/链接,例如:
在这样做之后,我能够得到以下示例代码,其中PASSWORD代表key.pem的密码,TOKEN代表我的设备代币:
var apn = require("apn");
var path = require('path');
try {
var options = {
cert: path.join(__dirname, 'cert.pem'), // Certificate file path
key: path.join(__dirname, 'key.pem'), // Key file path
passphrase: '<PASSWORD>', // A passphrase for the Key file
ca: path.join(__dirname, 'aps_development.cer'),// String or Buffer of CA data to use for the TLS connection
production:false,
gateway: 'gateway.sandbox.push.apple.com', // gateway address
port: 2195, // gateway port
enhanced: true // enable enhanced format
};
var apnConnection = new apn.Connection(options);
var myDevice = new apn.Device("<TOKEN>");
var note = new apn.Notification();
note.expiry = Math.floor(Date.now() / 1000) + 3600; // Expires 1 hour from now.
note.badge = 3;
note.sound = "ping.aiff";
note.alert = "You have a new message";
note.payload = {'msgFrom': 'Alex'};
note.device = myDevice;
apnConnection.pushNotification(note);
process.stdout.write("******* EXECUTED WITHOUT ERRORS************ :");
} catch (ex) {
process.stdout.write("ERROR :"+ex);
}
执行此代码时没有错误,但问题是我的iOS设备没有收到任何通知。我也试过设置ca:null&amp; debug:true(在选项var中)。但同样的事情发生了。
再次,当我使用ck.pem&amp;我拥有的设备令牌并将其与PHP一起使用,它可以工作,但我无法在Node JS中使用它。请帮助!!
非常感谢你!
答案 0 :(得分:3)
您可能正在遇到NodeJS本身的异步特性。我使用相同的node-apn
模块取得了巨大成功。但是你不能像在PHP中习惯的那样直接调用它 - 这是一个不能从PHP-&gt;节点映射的同步模型。您的进程在实际发生任何事情之前就会退出 - apnConnection.pushNotification(note);
是一个异步调用,在您的脚本返回/退出之前几乎没有启动。
正如node-apn
文档中所述,您可能希望&#34;倾听&#34; apnConnection
上的其他活动。这是我用来注销创建后连接上发生的各种事件的代码摘录:
// We were unable to initialize the APN layer - most likely a cert issue.
connection.on('error', function(error) {
console.error('APNS: Initialization error', error);
});
// A submission action has completed. This just means the message was submitted, not actually delivered.
connection.on('completed', function(a) {
console.log('APNS: Completed sending', a);
});
// A message has been transmitted.
connection.on('transmitted', function(notification, device) {
console.log('APNS: Successfully transmitted message');
});
// There was a problem sending a message.
connection.on('transmissionError', function(errorCode, notification, device) {
var deviceToken = device.toString('hex').toUpperCase();
if (errorCode === 8) {
console.log('APNS: Transmission error -- invalid token', errorCode, deviceToken);
// Do something with deviceToken here - delete it from the database?
} else {
console.error('APNS: Transmission error', errorCode, deviceToken);
}
});
connection.on('connected', function() {
console.log('APNS: Connected');
});
connection.on('timeout', function() {
console.error('APNS: Connection timeout');
});
connection.on('disconnected', function() {
console.error('APNS: Lost connection');
});
connection.on('socketError', console.log);
同样重要的是,您需要确保在处理异步请求时脚本保持运行状态。大多数情况下,当您构建越来越大的服务时,您最终将会遇到某种类型的事件循环,而ActionHero,ExpressJS,Sails等框架将为您完成此任务。
与此同时,你可以用这个超级原油循环确认它,这只会强制进程继续运行,直到你点击 CTRL + C :
setInterval(function() {
console.log('Waiting for events...');
}, 5000);
答案 1 :(得分:0)
我将用简单的代码进行解释
需要代码中的那个模块
var apn = require('apn');
let service = new apn.Provider({
cert: "apns.pem",
key: "p12Cert.pem",
passphrase:"123456",
production: true //use this when you are using your application in production.For development it doesn't need
});
let note = new apn.Notification({
payload:{
"staffid":admins[j]._id,
"schoolid":admins[j].schoolid,
"prgmid":resultt.programid
},
category:"Billing",
alert:"Fee payment is pending for your approval",
sound:"ping.aiff",
topic:"com.xxx.yyy",//this is the bundle name of your application.This key is needed for production
contentAvailable: 1//this key is also needed for production
});
console.log(`Sending: ${note.compile()} to ${ios}`);
services.send(note, ios).then( result => {//ios key is holding array of device ID's to which notification has to be sent
console.log("sent:", result.sent.length);
console.log("failed:", result.failed.length);
console.log(result.failed);
});
services.shutdown();
在有效负载中,您可以使用自定义密钥发送数据。希望对您有所帮助
答案 2 :(得分:0)
仍然面临问题,请尝试
note.topic = "com.YOURWESITENAME.app";