ssl - Erlang Apple 推送通知在断开连接前未收到响应错误

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

我目前正在测试我的推送通知模块。 当 Device Token 无效时,它会断开连接...

根据 Apple push notification developer documentation我应该在苹果推送服务器断开连接之前收到一个错误响应数据包......

问题是我断开了连接,但在此之前我在 Socket 上没有得到任何东西,我需要知道推送失败是因为推送格式错误(这样我可以修复错误)还是无效设备 token (这样我就可以将其从数据库中删除)。

这是我的代码:

-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, state, cert, key}).

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

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

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, true}],
    Timeout = 1000,
    {ok, Socket} = ssl:connect(Address, Port, Options, Timeout),
    {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.

当 payload 和 deviceToken 都正确时,效果很好。如果 deviceToken 无效,它只会断开连接。

有人能发现问题吗?因为找了4个小时,我才发现我明明做不到!

这是错误响应表:

Status code     Description
0           No errors encountered
1           Processing error
2           Missing device token
3           Missing topic
4           Missing payload
5           Invalid token size
6           Invalid topic size
7           Invalid payload size
8           Invalid token
255         None (unknown)

最佳答案

您似乎正在使用链接到的苹果文档中图 5-1 定义的简单通知格式(根据您的 send() 函数判断).使用此格式时,如果请求格式错误,则不会提供错误响应 - 您只会断开连接。

要获得错误响应,您应该使用图 5-2 中详述的增强通知格式

关于ssl - Erlang Apple 推送通知在断开连接前未收到响应错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10667451/

相关文章:

二郎; OTP 申请 "app.config"

ios - 是否可以拦截另一个应用程序的推送通知?

ios - 来自 CloudKit 的推送通知未正确同步

java - 给jvm添加不同的p12证书

apache - 从 www 重定向到非 www

c# - 如何在 C# 中发送 HTTPS GET 请求

erlang - 如何找出 Erlang 进程 (PID) 在哪个节点上运行?

string - Erlang替换字符串中的子字符串

ios - 开发aps证书被吊销了,为什么还能推送通知?

django - 白名单 http : content for Django application running SSL?