3

현재 얼랭에 대한 푸시 알림 모듈을 만들려고합니다.얼랭 + Apple 푸시 알림 [유효하지 않은 토큰 문제]

토큰이 유효하면 모든 것이 훌륭하게 작동합니다 ... 문제는 이전의 장치 토큰 (현재는 유효하지 않음)이 거부 된 것입니다. 유효하지 않은 토큰이 6 바이트 소켓 메시지가있는 apns에 의해 거부되고 연결이 무효화된다는 것을 이해합니다. (어떤 것이 든 실제로는 바보라고 생각합니다.)

문제는 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. 

, 난에 다음 푸시는 전화 수신, 유효한 토큰에 밀어하지만 잘못된 토큰 누를 때, 그리고 다음은

내 코드입니다 유효한 토큰이면 유효한 토큰은 푸시를받지 못합니다 ...

내 데이터베이스에서 장치 토큰을 제거하기 위해 피드백 서비스를 청취해야한다는 것을 알고 있지만, 푸시 다시 연결하기 위해 게이트웨이가 무효화되었습니다.

그래서 여기가 실제 질문입니다 : 내 세대 서버가합니다 (handle_info ({SSL, 소켓, 데이터}, P)과 일치한다) 오류 응답 패킷을 수신하지 않는 이유는 무엇입니까?

답변

4

소켓은 active = false로 구성됩니다. 활성 = true (또는 반복적으로 활성 = 한 번)으로 설정하지 않으면 메시지가 수신되지 않습니다. inet:setopts/2에 대한 설명서를 참조하십시오.

제어 프로세스를 self()로 설정할 필요가 없습니다.

+0

Gen_server가 ssl_close 핸들을 호출합니다. 이상하게도 오류 응답 패킷을받지 못합니다. 소켓 연결이 끊어 졌을 때 알 수 있습니다. 유효 +1 정확함 대답. – TheSquad

+0

@SheSquad는 오류가 다시 발생하지 않는 기존의 "간단한 알림 형식"을 사용하는 것처럼 보입니다. 닫힌 소켓 일뿐입니다. 기존의 "향상된"(단순한 형식과 상당히 유사 함) 또는 현재 이진 형식을 사용해보십시오. error-response-id 다음에 보류중인 알림을 다시 전송해야합니다. –