3

我正在嘗試爲Erlang創建推送通知模塊。Erlang + Apple推送通知[無效令牌問題]

當令牌有效時,一切正常... 問題是舊設備令牌(現在無效)被拒絕。 據我所知,無效令牌將被6字節套接字消息的apns拒絕,並使連接無效(我認爲這真是愚蠢的,無論...)

事情是我似乎並沒有得到6字節的套接字消息,APNS應該給我的模塊,就像控制進程沒有監聽套接字一樣。

這裏是我的代碼:

-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. 

所以當我啓動模塊,並且我推到一個有效的令牌,推是在手機上收到的,但是當我推到一個無效的令牌,然後一個有效的令牌,有效的令牌將不會收到任何推...

我知道我應該聽取反饋服務,以從我的數據庫中刪除設備令牌,但我也需要知道是否推網關爲了重新連接而失效了我的連接。

這是real問題:爲什麼我的gen-server沒有收到錯誤響應數據包(它應該與handle_info({ssl,Socket,Data},P))相匹配?

回答

4

您的套接字配置爲active = false。除非將其設置爲active = true(或反覆激活=一次),否則不會收到任何消息。請參閱inet:setopts/2的文檔。

您也不應該將controls_process設置爲self()。

+0

你說得對,現在gen_server調用ssl_close句柄......奇怪的是我沒有收到錯誤響應包,不管怎樣,我可以知道套接字何時斷開連接,我問了所有問題;-)有效的+1精確回答。 – TheSquad 2012-03-21 23:51:32

+0

@TheSquad看起來像您使用的傳統「簡單通知格式」,您不會收到錯誤,只是一個封閉的套接字。嘗試使用現在的「增強」(與簡單格式非常相似)或當前的二進制格式。請記住在錯誤響應ID後重新發送掛起的通知。 – 2014-01-20 16:36:51