22

Erlangを使用してAPNにプッシュ通知を送信しようとしています。これは私がこれまでに思いついたコードです:

-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の並行性を利用していませんが、単なるプロトタイプです。最も簡単な方法でプッシュを送信できるかどうかをテストしたいだけです。

問題は、APNに送信されるパケットにあると思います。これは、プッシュ通知のバイナリ形式です。

代替テキストhttp://developer.apple.com/IPhone/library/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Art/aps_provider_binary.jpg

Erlangでそのようなパケットを作成するにはどうすればよいですか?誰かが私のコードを見て、問題がどこにあるか教えてもらえますか?
また、ErlangのSSLアプリケーションを使用して接続を作成し、データを送信しましたが、これが問題なのかパケットなのかわかりません。
ありがとう!

4

3 に答える 3

23

まず、単一のバイナリのリストを作成してから呼び出す必要はありませんlist_to_binary/1。バイナリ自体を送信するだけです。

また、フィールドの長さと値がプロトコルに従って適切であることを確認してください。

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

ここまで進んだので、length(Token)は実際には32ではなく64であることがわかります。Tokenの16進文字列をバイナリに変換するのを忘れたため、32ではなく64バイトの16進文字列を送信しています。バイナリバイト。

つまり...Payloadを最初からバイナリにし、Tokenを数値定数にすると、次のようなことができます。

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に感謝します。

于 2009-11-18T16:34:37.977 に答える
4

私は2つの間違いを見ます:

  • トークンは、16進数のASCIIではなく、2進数で渡す必要があります。
  • バイナリ構文を使用してリストをバイナリに変換することはできません。

16進数を整数に解析してから、2進数に解析するには、次のようなものを使用します。

Token = "dead",
TokenNum = erlang:list_to_integer(Token, 16),
TokenBin = <<TokenNum:32/integer-unit:8>>,

次のようなプロトコルパケットを作成します。

TokenBin = ...,
Payload = <<"Payload">>,
PayloadSize = byte_size(Payload),
Packet = <<0:8, 32:16, TokenBin/binary, PayloadSize:16, Payload/binary>>,
于 2009-11-18T17:41:44.027 に答える
1

簡単なライブラリepns(Erlangプッシュ通知)を使用してみてください

このライブラリは、Erlang側でAPNSおよびFCMとしてプッシュ通知を送信できます。epns(Erlangプッシュ通知)ライブラリの使用方法-README.mdで読むことができます。このライブラリは、プロジェクトでサードパーティとして使用できます。または、ローカルで実行して、このライブラリがどのように機能するかを確認することもできます。

$ git clone https://github.com/vkatsuba/epns.git
$ cd epns
$ make

Erlang 20〜21で再テスト

于 2019-08-01T09:07:21.753 に答える