fix
This commit is contained in:
parent
c5ee4eec0a
commit
ad518db266
@ -6,7 +6,7 @@
|
||||
%%% @end
|
||||
%%% Created : 02. 4月 2025 19:09
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(dimension_apn_pusher).
|
||||
-module(dimension_apn_worker).
|
||||
-author("anlicheng").
|
||||
|
||||
-behaviour(gen_server).
|
||||
@ -14,7 +14,6 @@
|
||||
%% API
|
||||
-export([start_link/1]).
|
||||
-export([push/4]).
|
||||
-export([test/1]).
|
||||
|
||||
%% gen_server callbacks
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
|
||||
@ -30,14 +29,9 @@
|
||||
%%% API
|
||||
%%%===================================================================
|
||||
|
||||
test(DeviceToken) ->
|
||||
Title = <<"这是一个消息通知"/utf8>>,
|
||||
Body = jiffy:encode(#{<<"id">> => 1234, <<"name">> => <<"英雄第二季"/utf8>>}, [force_utf8]),
|
||||
gen_server:cast(?SERVER, {push, DeviceToken, Title, Body}).
|
||||
|
||||
-spec push(Pid :: pid(), DeviceToken :: binary(), Title :: binary(), Body :: binary()) -> no_return().
|
||||
push(Pid, DeviceToken, Title, Body) when is_pid(Pid), is_binary(DeviceToken), is_binary(Title), is_binary(Body) ->
|
||||
gen_server:cast(Pid, {push, DeviceToken, Title, Body}).
|
||||
gen_server:call(Pid, {push, DeviceToken, Title, Body}).
|
||||
|
||||
%% @doc Spawns the server and registers the local name (unique)
|
||||
-spec(start_link(Opts :: list()) ->
|
||||
@ -69,6 +63,73 @@ init([Props]) ->
|
||||
|
||||
{ok, #state{apns_pid = ApnsPid, headers = Headers}}.
|
||||
|
||||
%% @private
|
||||
%% @doc Handling call messages
|
||||
-spec(handle_call(Request :: term(), From :: {pid(), Tag :: term()},
|
||||
State :: #state{}) ->
|
||||
{reply, Reply :: term(), NewState :: #state{}} |
|
||||
{reply, Reply :: term(), NewState :: #state{}, timeout() | hibernate} |
|
||||
{noreply, NewState :: #state{}} |
|
||||
{noreply, NewState :: #state{}, timeout() | hibernate} |
|
||||
{stop, Reason :: term(), Reply :: term(), NewState :: #state{}} |
|
||||
{stop, Reason :: term(), NewState :: #state{}}).
|
||||
handle_call({push, DeviceToken, Title, Body}, _From, State = #state{apns_pid = ApnsPid, headers = Headers}) ->
|
||||
Notification = #{
|
||||
aps => #{
|
||||
alert => #{
|
||||
title => Title,
|
||||
body => Body
|
||||
},
|
||||
% 播放默认声音
|
||||
sound => <<"default">>,
|
||||
% App 图标角标
|
||||
badge => 1
|
||||
}
|
||||
},
|
||||
PushResult = apns:push_notification(ApnsPid, DeviceToken, Notification, Headers),
|
||||
lager:debug("[dimension_apn_pusher] push result is: ~p", [PushResult]),
|
||||
{reply, ok, State}.
|
||||
|
||||
%% @private
|
||||
%% @doc Handling cast messages
|
||||
-spec(handle_cast(Request :: term(), State :: #state{}) ->
|
||||
{noreply, NewState :: #state{}} |
|
||||
{noreply, NewState :: #state{}, timeout() | hibernate} |
|
||||
{stop, Reason :: term(), NewState :: #state{}}).
|
||||
handle_cast(_Request, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
%% @private
|
||||
%% @doc Handling all non call/cast messages
|
||||
-spec(handle_info(Info :: timeout() | term(), State :: #state{}) ->
|
||||
{noreply, NewState :: #state{}} |
|
||||
{noreply, NewState :: #state{}, timeout() | hibernate} |
|
||||
{stop, Reason :: term(), NewState :: #state{}}).
|
||||
handle_info(_Info, State = #state{}) ->
|
||||
{noreply, State}.
|
||||
|
||||
%% @private
|
||||
%% @doc This function is called by a gen_server when it is about to
|
||||
%% terminate. It should be the opposite of Module:init/1 and do any
|
||||
%% necessary cleaning up. When it returns, the gen_server terminates
|
||||
%% with Reason. The return value is ignored.
|
||||
-spec(terminate(Reason :: (normal | shutdown | {shutdown, term()} | term()),
|
||||
State :: #state{}) -> term()).
|
||||
terminate(_Reason, _State = #state{}) ->
|
||||
ok.
|
||||
|
||||
%% @private
|
||||
%% @doc Convert process state when code is changed
|
||||
-spec(code_change(OldVsn :: term() | {down, term()}, State :: #state{},
|
||||
Extra :: term()) ->
|
||||
{ok, NewState :: #state{}} | {error, Reason :: term()}).
|
||||
code_change(_OldVsn, State = #state{}, _Extra) ->
|
||||
{ok, State}.
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
|
||||
-spec parse_headers(Headers :: list()) -> map().
|
||||
parse_headers(Headers) ->
|
||||
parse_headers(Headers, #{}).
|
||||
@ -112,72 +173,4 @@ connection_opts([{type, Type}|ConnectionOpts], Acc) ->
|
||||
connection_opts([{timeout, Timeout}|ConnectionOpts], Acc) ->
|
||||
connection_opts(ConnectionOpts, Acc#{timeout => Timeout});
|
||||
connection_opts([_|ConnectionOpts], Acc) ->
|
||||
connection_opts(ConnectionOpts, Acc).
|
||||
|
||||
%% @private
|
||||
%% @doc Handling call messages
|
||||
-spec(handle_call(Request :: term(), From :: {pid(), Tag :: term()},
|
||||
State :: #state{}) ->
|
||||
{reply, Reply :: term(), NewState :: #state{}} |
|
||||
{reply, Reply :: term(), NewState :: #state{}, timeout() | hibernate} |
|
||||
{noreply, NewState :: #state{}} |
|
||||
{noreply, NewState :: #state{}, timeout() | hibernate} |
|
||||
{stop, Reason :: term(), Reply :: term(), NewState :: #state{}} |
|
||||
{stop, Reason :: term(), NewState :: #state{}}).
|
||||
handle_call(_Request, _From, State = #state{}) ->
|
||||
{reply, ok, State}.
|
||||
|
||||
%% @private
|
||||
%% @doc Handling cast messages
|
||||
-spec(handle_cast(Request :: term(), State :: #state{}) ->
|
||||
{noreply, NewState :: #state{}} |
|
||||
{noreply, NewState :: #state{}, timeout() | hibernate} |
|
||||
{stop, Reason :: term(), NewState :: #state{}}).
|
||||
handle_cast({push, DeviceToken, Title, Body}, State = #state{apns_pid = ApnsPid, headers = Headers}) ->
|
||||
Notification = #{
|
||||
aps => #{
|
||||
alert => #{
|
||||
title => Title,
|
||||
body => Body
|
||||
},
|
||||
% 播放默认声音
|
||||
sound => <<"default">>,
|
||||
% App 图标角标
|
||||
badge => 1
|
||||
}
|
||||
},
|
||||
PushResult = apns:push_notification(ApnsPid, DeviceToken, Notification, Headers),
|
||||
lager:debug("[dimension_apn_pusher] push result is: ~p", [PushResult]),
|
||||
|
||||
{noreply, State}.
|
||||
|
||||
%% @private
|
||||
%% @doc Handling all non call/cast messages
|
||||
-spec(handle_info(Info :: timeout() | term(), State :: #state{}) ->
|
||||
{noreply, NewState :: #state{}} |
|
||||
{noreply, NewState :: #state{}, timeout() | hibernate} |
|
||||
{stop, Reason :: term(), NewState :: #state{}}).
|
||||
handle_info(_Info, State = #state{}) ->
|
||||
{noreply, State}.
|
||||
|
||||
%% @private
|
||||
%% @doc This function is called by a gen_server when it is about to
|
||||
%% terminate. It should be the opposite of Module:init/1 and do any
|
||||
%% necessary cleaning up. When it returns, the gen_server terminates
|
||||
%% with Reason. The return value is ignored.
|
||||
-spec(terminate(Reason :: (normal | shutdown | {shutdown, term()} | term()),
|
||||
State :: #state{}) -> term()).
|
||||
terminate(_Reason, _State = #state{}) ->
|
||||
ok.
|
||||
|
||||
%% @private
|
||||
%% @doc Convert process state when code is changed
|
||||
-spec(code_change(OldVsn :: term() | {down, term()}, State :: #state{},
|
||||
Extra :: term()) ->
|
||||
{ok, NewState :: #state{}} | {error, Reason :: term()}).
|
||||
code_change(_OldVsn, State = #state{}, _Extra) ->
|
||||
{ok, State}.
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
connection_opts(ConnectionOpts, Acc).
|
||||
25
apps/dimension_apn/src/dimension_spn_pusher.erl
Normal file
25
apps/dimension_apn/src/dimension_spn_pusher.erl
Normal file
@ -0,0 +1,25 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @author anlicheng
|
||||
%%% @copyright (C) 2025, <COMPANY>
|
||||
%%% @doc
|
||||
%%%
|
||||
%%% @end
|
||||
%%% Created : 03. 4月 2025 15:41
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(dimension_spn_pusher).
|
||||
-author("anlicheng").
|
||||
|
||||
%% API
|
||||
-export([push/3]).
|
||||
-export([test/1]).
|
||||
|
||||
test(DeviceToken) ->
|
||||
Title = <<"这是一个消息通知"/utf8>>,
|
||||
Body = jiffy:encode(#{<<"id">> => 1234, <<"name">> => <<"英雄第二季"/utf8>>}, [force_utf8]),
|
||||
push(DeviceToken, Title, Body).
|
||||
|
||||
-spec push(DeviceToken :: binary(), Title :: binary(), Body :: binary()) -> no_return().
|
||||
push(DeviceToken, Title, Body) when is_binary(DeviceToken), is_binary(Title), is_binary(Body) ->
|
||||
poolboy:transaction(apns_pool, fun(WorkerPid) ->
|
||||
dimension_apn_worker:push(WorkerPid, DeviceToken, Title, Body)
|
||||
end).
|
||||
@ -12,7 +12,7 @@
|
||||
{pools, [
|
||||
%% 推送设置
|
||||
{apns_pool,
|
||||
[{size, 1}, {max_overflow, 1}, {worker_module, dimension_apn_pusher}],
|
||||
[{size, 1}, {max_overflow, 1}, {worker_module, dimension_apn_worker}],
|
||||
[
|
||||
{connection_opts, [
|
||||
{apple_host, "api.sandbox.push.apple.com"},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user