使用Node JS

时间:2016-04-14 20:19:41

标签: ios node.js apple-push-notifications apn

我希望创建APNS(Apple推送通知服务),服务器将向iOS设备发送通知。 我可以使用SAME设备令牌和SAME证书通过PHP进行推送通知,但是,我想通过Node JS而不是PHP发送通知。

我有以下有效的文件/证书来帮助我入门:

  • cert.pem
  • key.pem
  • aps_development.cer
  • cert.p12
  • key.p12,
  • ck.pem

我一直在浏览几个资源/链接,例如:

在这样做之后,我能够得到以下示例代码,其中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中使用它。请帮助!!

非常感谢你!

3 个答案:

答案 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)

我将用简单的代码进行解释

  1. 首先使用此命令 npm install apn 安装 apn 模块。
  2. 需要代码中的那个模块

    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
        });
    
  3. 这是通知的主要内容

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";