如何使用 Erlang 发送推送通知? [英] How to send a push notification using Erlang?

查看:27
本文介绍了如何使用 Erlang 发送推送通知?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Erlang 向 APNs 发送推送通知.这是我到目前为止想出的代码:

I'm trying to send a push notification to APNs using Erlang. This is the code I came up with so far:

-module(apnstest2).
-export([connect/0]).

connect() ->
    application:start(ssl),
    ssl:seed("someseedstring"),
    Address = "gateway.sandbox.push.apple.com",
    Port = 2195,
    Cert = "/path/to/Certificate.pem",
    Key = "/path/to/Key.unenc.pem",
    Options = [{certfile, Cert}, {keyfile, Key}, {mode, binary}],
    Timeout = 1000,
    {ok, Socket} = ssl:connect(Address, Port, Options, Timeout),

    Token = "195ec05a962b24954693c0b638b6216579a0d1d74b3e1c6f534c6f8fd0d50d03",
    Payload = "{\"aps\":{\"alert\":\"Just testing.\",\"sound\":\"chime\", \"badge\":10}}",
    TokenLength = length(Token),
    PayloadLength = length(Payload),

    Packet = [<<0:8, TokenLength, Token, PayloadLength, Payload>>],

    ssl:send(Socket, list_to_binary(Packet)),
    ssl:close(Socket).

代码没有利用Erlang的并发性,只是一个原型.我只想测试能不能用最简单的方式发送推送.

The code doesn't take advantage of Erlang's concurrency but is just a prototype. I only want to test if I can send the push in the most simple way.

我认为问题在于发送到 APN 的数据包.这是推送通知的二进制格式:

I think the problem is in the packet being sent to the APNs. This is the binary format of a push notification:

替代文字 http://developer.apple.com/IPhone/library/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Art/aps_provider_binary.jpg

我应该如何在 Erlang 中创建这样的数据包?有人可以看看我的代码并告诉我问题出在哪里吗?
另外我使用Erlang的SSL应用程序来创建连接并发送数据,我不知道这是问题还是数据包.
谢谢!

How should I create such a packet in Erlang? Could someone please take a look at my code and tell me where the problem is?
Also I used Erlang's SSL application to create the connection and send the data and I don't know if this is the problem or the packet.
Thanks!

推荐答案

首先,无需创建单个二进制文件的列表,然后对其调用 list_to_binary/1.您可以直接发送二进制文件本身.

To start with, there is no need for creating a list of a single binary and then calling list_to_binary/1 on it. You can just send the binary itself.

另外,根据协议确保字段长度和值是合适的:

Also, make sure the field lengths and values are appropriate according to the protocol:

TokenLength = 32 = length(Token),
Packet = <<0:8, TokenLength:16/big, Token, PayloadLength:16/big, Payload>>,
ssl:send(Socket, Packet),

既然我们已经到了这一步,我们将看到 length(Token) 实际上是 64,而不是 32:您忘记将 Token 的十六进制字符串转换为二进制,因此您发送的是 64 字节的十六进制字符串,而不是 32 个二进制字节.

Now that we have gotten this far, we will see that length(Token) is in fact 64, not 32: You forgot to convert the hex string for Token to a binary, so you are sending a 64 byte hex character string instead of 32 binary bytes.

所以...从一开始就将 Payload 设为二进制,并将 Token 设为数字常量,您可以执行以下操作:

So... making Payload a binary from the start, and making Token a numeric constant, you can do something like the following:

Payload = <<"{\"aps\":{\"alert\":\"Just testing.\",\"sound\":\"chime\", \"badge\":10}}">>,
PayloadLength = size(Payload),
Packet = <<0:8, 32:16/big,
          16#195ec05a962b24954693c0b638b6216579a0d1d74b3e1c6f534c6f8fd0d50d03:256/big,
          PayloadLength:16/big, Payload/binary>>,
ssl:send(Socket, Packet),

感谢 Christian 指出此答案以前修订版中的一些错误.

Thanks to Christian for pointing out a number of mistakes in the former revisions of this answer.

这篇关于如何使用 Erlang 发送推送通知?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆