Erlang + Apple推送通知[无效令牌问题]

时间:2012-03-21 14:19:48

标签: ssl erlang push-notification apple-push-notifications gen-server

我目前正在尝试为Erlang创建推送通知模块。

当令牌有效时,一切都很好...... 问题是当旧设备令牌(现在无效)被拒绝时。 我知道apns会使用6字节套接字消息拒绝无效令牌,并使连接无效(我认为这真的很愚蠢,无论如何......)

事情是我似乎没有获得APNS应该给我的模块的6字节套接字消息,就像控制进程没有监听套接字一样。

这是我的代码:

-module(pushiphone).
-behaviour(gen_server).

-export([start/1, init/1, handle_call/3, handle_cast/2, code_change/3, handle_info/2, terminate/2]).

-import(ssl, [connect/4]).
-record(push, {socket, pid, state, cert, key}).

start(Provisioning) ->
    gen_server:start_link(?MODULE, [Provisioning], []).

init([Provisioning]) ->
    gen_server:cast(self(), {connect, Provisioning}),
    {ok, #push{pid=self()}}.

send(Socket, DT, Payload) ->
    PayloadLen = length(Payload),
    DTLen = size(DT),
    PayloadBin = list_to_binary(Payload),
    Packet = <<0:8, 
           DTLen:16/big, 
           DT/binary, 
           PayloadLen:16/big, 
           PayloadBin/binary>>,
    ssl:send(Socket, Packet).

handle_call(_, _, P) ->
    {noreply, P}.

handle_cast({connect, Provisioning}, P) ->
    case Provisioning of
    dev -> Address = "gateway.sandbox.push.apple.com";
    prod -> Address = "gateway.push.apple.com"
    end,
    Port = 2195,
    Cert="/apns-" ++ atom_to_list(Provisioning) ++ "-cert.pem",
    Key="/apns-" ++ atom_to_list(Provisioning) ++ "-key.pem",
    Options = [{certfile, Cert}, {keyfile, Key}, {password, "********"}, {mode, binary}, {active, false}],
    Timeout = 1000,
    {ok, Socket} = ssl:connect(Address, Port, Options, Timeout),
    ssl:controlling_process(Socket, self()), %% Necessary ??
    gproc:reg({n,l, pushiphone}),
    {noreply, P#push{socket=Socket}};
handle_cast(_, P) ->
    {noreply, P}.

handle_info({ssl, Socket, Data}, P) ->
    <<Command, Status, SomeID:32/big>> = Data,
    io:fwrite("[PUSH][ERROR]: ~p / ~p / ~p~n", [Command, Status, SomeID]),
    ssl:close(Socket),
    {noreply, P};
handle_info({push, message, DT, Badge, [Message]}, P) ->
    Payload = "{\"aps\":{\"alert\":\"" ++ Message ++ "\",\"badge\":" ++ Badge ++ ",\"sound\":\"" ++ "msg.caf" ++ "\"}}",
    send(P#push.socket, DT, Payload),
    {noreply, P};
handle_info({ssl_closed, _SslSocket}, P) ->
    io:fwrite("SSL CLOSED !!!!!!~n"),
    {stop, normal, P};
handle_info(AnythingElse, P) ->
    io:fwrite("[ERROR][PUSH][ANYTHING ELSE] : ~p~n", [AnythingElse]),
    {noreply, P}.

code_change(_, P, _) ->
    {ok, P}.

terminate(_, _) ->
    ok.

因此,当我启动模块并推送到有效令牌时,手机会收到推送,但是当我推送到无效令牌,然后推送到有效令牌时,有效令牌将不会收到任何令牌。推...

我知道我应该收听反馈服务,以便从我的数据库中删除设备令牌,但我还需要知道推送网关是否使我的连接无效以便重新连接。

所以这是真正的问题:为什么我的gen-server没有收到错误响应数据包(应该与handle_info匹配({ssl,Socket,Data},P))?< / p>

1 个答案:

答案 0 :(得分:4)

您的套接字配置为active = false。除非您将其设置为active = true(或反复激活=一次),否则您将不会收到任何消息。请参阅inet:setopts/2的文档。

您也不必将controlling_process设置为self()。