Compare commits
No commits in common. "9d27ba3a6a70b62b9de200a56897b730627c6025" and "ad518db26625d0ec465df2d58091f4a23978c301" have entirely different histories.
9d27ba3a6a
...
ad518db266
@ -1,15 +0,0 @@
|
|||||||
%%%-------------------------------------------------------------------
|
|
||||||
%%% @author anlicheng
|
|
||||||
%%% @copyright (C) 2025, <COMPANY>
|
|
||||||
%%% @doc
|
|
||||||
%%%
|
|
||||||
%%% @end
|
|
||||||
%%% Created : 07. 4月 2025 14:34
|
|
||||||
%%%-------------------------------------------------------------------
|
|
||||||
-author("anlicheng").
|
|
||||||
|
|
||||||
-record(device_token, {
|
|
||||||
user_id :: binary(),
|
|
||||||
token :: binary(),
|
|
||||||
timestamp = 0 :: integer()
|
|
||||||
}).
|
|
||||||
@ -1,107 +0,0 @@
|
|||||||
%%%-------------------------------------------------------------------
|
|
||||||
%%% @author licheng5
|
|
||||||
%%% @copyright (C) 2020, <COMPANY>
|
|
||||||
%%% @doc
|
|
||||||
%%%
|
|
||||||
%%% @end
|
|
||||||
%%% Created : 26. 4月 2020 3:36 下午
|
|
||||||
%%%-------------------------------------------------------------------
|
|
||||||
-module(api_handler).
|
|
||||||
-author("licheng5").
|
|
||||||
|
|
||||||
%% API
|
|
||||||
-export([init/2]).
|
|
||||||
|
|
||||||
init(Req0, Opts) ->
|
|
||||||
Method = binary_to_list(cowboy_req:method(Req0)),
|
|
||||||
Path = binary_to_list(cowboy_req:path(Req0)),
|
|
||||||
GetParams0 = cowboy_req:parse_qs(Req0),
|
|
||||||
GetParams = maps:from_list(GetParams0),
|
|
||||||
{ok, PostParams, Req1} = parse_body(Req0),
|
|
||||||
|
|
||||||
try handle_request(Method, Path, GetParams, PostParams) of
|
|
||||||
{ok, StatusCode, Resp} ->
|
|
||||||
lager:debug("[http_protocol] request path: ~p, get_params: ~p, post_params: ~p, response: ~ts",
|
|
||||||
[Path, GetParams, PostParams, Resp]),
|
|
||||||
AcceptEncoding = cowboy_req:header(<<"accept-encoding">>, Req1, <<>>),
|
|
||||||
Req2 = case iolist_size(Resp) >= 1024 andalso supported_gzip(AcceptEncoding) of
|
|
||||||
true ->
|
|
||||||
Resp1 = zlib:gzip(Resp),
|
|
||||||
cowboy_req:reply(StatusCode, #{
|
|
||||||
<<"Content-Type">> => <<"application/json;charset=utf-8">>,
|
|
||||||
<<"Content-Encoding">> => <<"gzip">>
|
|
||||||
}, Resp1, Req1);
|
|
||||||
false ->
|
|
||||||
cowboy_req:reply(StatusCode, #{
|
|
||||||
<<"Content-Type">> => <<"application/json;charset=utf-8">>
|
|
||||||
}, Resp, Req1)
|
|
||||||
end,
|
|
||||||
{ok, Req2, Opts}
|
|
||||||
catch
|
|
||||||
throw:Error ->
|
|
||||||
ErrResp = dimension_utils:json_error(-1, Error),
|
|
||||||
Req2 = cowboy_req:reply(404, #{
|
|
||||||
<<"Content-Type">> => <<"application/json;charset=utf-8">>
|
|
||||||
}, ErrResp, Req1),
|
|
||||||
{ok, Req2, Opts};
|
|
||||||
_:Error:Stack ->
|
|
||||||
lager:warning("[http_handler] get error: ~p, stack: ~p", [Error, Stack]),
|
|
||||||
Req2 = cowboy_req:reply(500, #{
|
|
||||||
<<"Content-Type">> => <<"text/html;charset=utf-8">>
|
|
||||||
}, <<"Internal Server Error">>, Req1),
|
|
||||||
{ok, Req2, Opts}
|
|
||||||
end.
|
|
||||||
|
|
||||||
%% 判断是否支持gzip
|
|
||||||
supported_gzip(AcceptEncoding) when is_binary(AcceptEncoding) ->
|
|
||||||
binary:match(AcceptEncoding, <<"gzip">>) =/= nomatch.
|
|
||||||
|
|
||||||
parse_body(Req0) ->
|
|
||||||
ContentType = cowboy_req:header(<<"content-type">>, Req0),
|
|
||||||
case ContentType of
|
|
||||||
<<"application/json", _/binary>> ->
|
|
||||||
{ok, Body, Req1} = read_body(Req0),
|
|
||||||
{ok, catch jiffy:decode(Body, [return_maps]), Req1};
|
|
||||||
<<"application/x-www-form-urlencoded">> ->
|
|
||||||
{ok, PostParams0, Req1} = cowboy_req:read_urlencoded_body(Req0),
|
|
||||||
PostParams = maps:from_list(PostParams0),
|
|
||||||
{ok, PostParams, Req1};
|
|
||||||
_ ->
|
|
||||||
{ok, #{}, Req0}
|
|
||||||
end.
|
|
||||||
|
|
||||||
%% 读取请求体
|
|
||||||
read_body(Req) ->
|
|
||||||
read_body(Req, <<>>).
|
|
||||||
read_body(Req, AccData) ->
|
|
||||||
case cowboy_req:read_body(Req) of
|
|
||||||
{ok, Data, Req1} ->
|
|
||||||
{ok, <<AccData/binary, Data/binary>>, Req1};
|
|
||||||
{more, Data, Req1} ->
|
|
||||||
read_body(Req1, <<AccData/binary, Data/binary>>)
|
|
||||||
end.
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
%% helper methods
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
|
|
||||||
%% 更新token信息
|
|
||||||
handle_request("POST", "/api/device_token", _, #{<<"user_id">> := UserId, <<"token">> := Token}) ->
|
|
||||||
case mnesia_device_token:insert(UserId, Token, dimension_utils:current_time()) of
|
|
||||||
ok ->
|
|
||||||
{ok, 200, dimension_utils:json_data(<<"success">>)};
|
|
||||||
{error, Reason} ->
|
|
||||||
lager:notice("[api_handler] insert user_id: ~p, token: ~p, error: ~p", [UserId, Token, Reason]),
|
|
||||||
{ok, 200, dimension_utils:json_error(-1, <<"更新token失败"/utf8>>)}
|
|
||||||
end;
|
|
||||||
|
|
||||||
%% 向用户推送数据
|
|
||||||
handle_request("POST", "/api/push", _, Notifications) ->
|
|
||||||
{ok, Pid} = dimension_apn_worker:start_link(),
|
|
||||||
dimension_apn_worker:push(Pid, Notifications),
|
|
||||||
|
|
||||||
{ok, 200, dimension_utils:json_data(<<"success">>)};
|
|
||||||
|
|
||||||
handle_request(_, Path, _, _) ->
|
|
||||||
Path1 = list_to_binary(Path),
|
|
||||||
{ok, 200, dimension_utils:json_error(-1, <<"url: ", Path1/binary, " not found">>)}.
|
|
||||||
@ -13,7 +13,6 @@
|
|||||||
ssl,
|
ssl,
|
||||||
jiffy,
|
jiffy,
|
||||||
apns,
|
apns,
|
||||||
mnesia,
|
|
||||||
kernel,
|
kernel,
|
||||||
stdlib
|
stdlib
|
||||||
]},
|
]},
|
||||||
|
|||||||
@ -10,12 +10,6 @@
|
|||||||
-export([start/2, stop/1]).
|
-export([start/2, stop/1]).
|
||||||
|
|
||||||
start(_StartType, _StartArgs) ->
|
start(_StartType, _StartArgs) ->
|
||||||
io:setopts([{encoding, unicode}]),
|
|
||||||
%% 加速内存的回收
|
|
||||||
erlang:system_flag(fullsweep_after, 16),
|
|
||||||
%% 启动mnesia
|
|
||||||
ok = mnesia:start(),
|
|
||||||
%% 启动http服务
|
|
||||||
start_http_server(),
|
start_http_server(),
|
||||||
dimension_apn_sup:start_link().
|
dimension_apn_sup:start_link().
|
||||||
|
|
||||||
@ -35,6 +29,10 @@ start_http_server() ->
|
|||||||
Dispatcher = cowboy_router:compile([
|
Dispatcher = cowboy_router:compile([
|
||||||
{'_', [
|
{'_', [
|
||||||
{"/api/[...]", http_protocol, [api_handler]},
|
{"/api/[...]", http_protocol, [api_handler]},
|
||||||
|
{"/host/[...]", http_protocol, [host_handler]},
|
||||||
|
{"/device/[...]", http_protocol, [device_handler]},
|
||||||
|
{"/totalizator/[...]", http_protocol, [totalizator_handler]},
|
||||||
|
{"/test/[...]", http_protocol, [test_handler]},
|
||||||
{"/ws", ws_channel, []}
|
{"/ws", ws_channel, []}
|
||||||
]}
|
]}
|
||||||
]),
|
]),
|
||||||
|
|||||||
@ -12,9 +12,8 @@
|
|||||||
-behaviour(gen_server).
|
-behaviour(gen_server).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([start_link/0]).
|
-export([start_link/1]).
|
||||||
-export([push/2]).
|
-export([push/4]).
|
||||||
-export([test/0]).
|
|
||||||
|
|
||||||
%% gen_server callbacks
|
%% gen_server callbacks
|
||||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
|
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
|
||||||
@ -30,37 +29,15 @@
|
|||||||
%%% API
|
%%% API
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
|
|
||||||
test() ->
|
-spec push(Pid :: pid(), DeviceToken :: binary(), Title :: binary(), Body :: binary()) -> no_return().
|
||||||
{ok, Pid} = start_link(),
|
push(Pid, DeviceToken, Title, Body) when is_pid(Pid), is_binary(DeviceToken), is_binary(Title), is_binary(Body) ->
|
||||||
UserId = <<"9df4dbb1-aff7-4caa-9adb-cb426a7dbcca">>,
|
gen_server:call(Pid, {push, DeviceToken, Title, Body}).
|
||||||
DeviceToken = <<"45fb2f5c960ab3c0b235088a87bfa5cddcb1109aa50f70c9b0fdd3d9482ec10a">>,
|
|
||||||
Title = <<"动物狂响曲"/utf8>>,
|
|
||||||
Body = <<"第7集(校服与被毛更深处),bilibili已更新"/utf8>>,
|
|
||||||
|
|
||||||
mnesia_device_token:insert(UserId, DeviceToken, dimension_utils:current_time()),
|
|
||||||
push(Pid, [
|
|
||||||
#{
|
|
||||||
<<"user_id">> => UserId,
|
|
||||||
<<"title">> => Title,
|
|
||||||
<<"body">> => Body,
|
|
||||||
<<"custom_data">> => #{
|
|
||||||
<<"target">> => <<"detail">>,
|
|
||||||
<<"params">> => #{
|
|
||||||
<<"drama_id">> => 1234
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]).
|
|
||||||
|
|
||||||
-spec push(Pid :: pid(), Notifications :: [map()]) -> no_return().
|
|
||||||
push(Pid, Notifications) when is_pid(Pid), is_list(Notifications) ->
|
|
||||||
gen_server:cast(Pid, {push, Notifications}).
|
|
||||||
|
|
||||||
%% @doc Spawns the server and registers the local name (unique)
|
%% @doc Spawns the server and registers the local name (unique)
|
||||||
-spec(start_link() ->
|
-spec(start_link(Opts :: list()) ->
|
||||||
{ok, Pid :: pid()} | ignore | {error, Reason :: term()}).
|
{ok, Pid :: pid()} | ignore | {error, Reason :: term()}).
|
||||||
start_link() ->
|
start_link(Props) when is_list(Props) ->
|
||||||
gen_server:start_link(?MODULE, [], []).
|
gen_server:start_link(?MODULE, [Props], []).
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% gen_server callbacks
|
%%% gen_server callbacks
|
||||||
@ -71,8 +48,7 @@ start_link() ->
|
|||||||
-spec(init(Args :: term()) ->
|
-spec(init(Args :: term()) ->
|
||||||
{ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} |
|
{ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} |
|
||||||
{stop, Reason :: term()} | ignore).
|
{stop, Reason :: term()} | ignore).
|
||||||
init([]) ->
|
init([Props]) ->
|
||||||
{ok, Props} = application:get_env(dimension_apn, apns),
|
|
||||||
ConnectionOpts0 = proplists:get_value(connection_opts, Props),
|
ConnectionOpts0 = proplists:get_value(connection_opts, Props),
|
||||||
Headers0 = proplists:get_value(headers, Props),
|
Headers0 = proplists:get_value(headers, Props),
|
||||||
|
|
||||||
@ -97,7 +73,21 @@ init([]) ->
|
|||||||
{noreply, NewState :: #state{}, timeout() | hibernate} |
|
{noreply, NewState :: #state{}, timeout() | hibernate} |
|
||||||
{stop, Reason :: term(), Reply :: term(), NewState :: #state{}} |
|
{stop, Reason :: term(), Reply :: term(), NewState :: #state{}} |
|
||||||
{stop, Reason :: term(), NewState :: #state{}}).
|
{stop, Reason :: term(), NewState :: #state{}}).
|
||||||
handle_call(_Request, _From, 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}.
|
{reply, ok, State}.
|
||||||
|
|
||||||
%% @private
|
%% @private
|
||||||
@ -106,13 +96,6 @@ handle_call(_Request, _From, State) ->
|
|||||||
{noreply, NewState :: #state{}} |
|
{noreply, NewState :: #state{}} |
|
||||||
{noreply, NewState :: #state{}, timeout() | hibernate} |
|
{noreply, NewState :: #state{}, timeout() | hibernate} |
|
||||||
{stop, Reason :: term(), NewState :: #state{}}).
|
{stop, Reason :: term(), NewState :: #state{}}).
|
||||||
handle_cast({push, Notifications}, State = #state{apns_pid = ApnsPid, headers = Headers}) ->
|
|
||||||
lists:foreach(fun(#{<<"user_id">> := UserId, <<"title">> := Title, <<"body">> := Body, <<"custom_data">> := CustomData}) ->
|
|
||||||
PushResult = push_task(ApnsPid, UserId, Title, Body, CustomData, Headers),
|
|
||||||
lager:debug("[dimension_apn_pusher] push result is: ~p", [PushResult])
|
|
||||||
end, Notifications),
|
|
||||||
{noreply, State};
|
|
||||||
|
|
||||||
handle_cast(_Request, State) ->
|
handle_cast(_Request, State) ->
|
||||||
{noreply, State}.
|
{noreply, State}.
|
||||||
|
|
||||||
@ -147,31 +130,6 @@ code_change(_OldVsn, State = #state{}, _Extra) ->
|
|||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
|
|
||||||
push_task(ApnsPid, UserId, Title, Body, CustomData, Headers)
|
|
||||||
when is_pid(ApnsPid), is_binary(UserId), is_binary(Title), is_binary(Body), is_map(CustomData), is_map(Headers) ->
|
|
||||||
|
|
||||||
case mnesia_device_token:get_token(UserId) of
|
|
||||||
error ->
|
|
||||||
ok;
|
|
||||||
{ok, DeviceToken} ->
|
|
||||||
Notification = #{
|
|
||||||
aps => #{
|
|
||||||
alert => #{
|
|
||||||
title => Title,
|
|
||||||
body => Body
|
|
||||||
},
|
|
||||||
'mutable-content' => 1,
|
|
||||||
% 播放默认声音
|
|
||||||
sound => <<"default">>,
|
|
||||||
% App 图标角标
|
|
||||||
badge => 1
|
|
||||||
% category => <<"HUB_MESSAGE">>
|
|
||||||
},
|
|
||||||
custom_data => CustomData
|
|
||||||
},
|
|
||||||
apns:push_notification(ApnsPid, DeviceToken, Notification, Headers)
|
|
||||||
end.
|
|
||||||
|
|
||||||
-spec parse_headers(Headers :: list()) -> map().
|
-spec parse_headers(Headers :: list()) -> map().
|
||||||
parse_headers(Headers) ->
|
parse_headers(Headers) ->
|
||||||
parse_headers(Headers, #{}).
|
parse_headers(Headers, #{}).
|
||||||
|
|||||||
@ -1,27 +0,0 @@
|
|||||||
%%%-------------------------------------------------------------------
|
|
||||||
%%% @author anlicheng
|
|
||||||
%%% @copyright (C) 2025, <COMPANY>
|
|
||||||
%%% @doc
|
|
||||||
%%%
|
|
||||||
%%% @end
|
|
||||||
%%% Created : 07. 4月 2025 15:47
|
|
||||||
%%%-------------------------------------------------------------------
|
|
||||||
-module(dimension_mnesia_manager).
|
|
||||||
-author("anlicheng").
|
|
||||||
|
|
||||||
%% API
|
|
||||||
-export([init_database/0]).
|
|
||||||
|
|
||||||
%% 只能调用一次
|
|
||||||
init_database() ->
|
|
||||||
%% 清理掉以前的schema
|
|
||||||
mnesia:stop(),
|
|
||||||
mnesia:delete_schema([node()]),
|
|
||||||
|
|
||||||
%% 创建schema
|
|
||||||
ok = mnesia:create_schema([node()]),
|
|
||||||
ok = mnesia:start(),
|
|
||||||
%% 创建数据库表
|
|
||||||
mnesia_device_token:create_table(),
|
|
||||||
|
|
||||||
ok.
|
|
||||||
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).
|
||||||
@ -1,31 +0,0 @@
|
|||||||
%%%-------------------------------------------------------------------
|
|
||||||
%%% @author anlicheng
|
|
||||||
%%% @copyright (C) 2025, <COMPANY>
|
|
||||||
%%% @doc
|
|
||||||
%%%
|
|
||||||
%%% @end
|
|
||||||
%%% Created : 07. 4月 2025 14:40
|
|
||||||
%%%-------------------------------------------------------------------
|
|
||||||
-module(dimension_utils).
|
|
||||||
-author("anlicheng").
|
|
||||||
|
|
||||||
%% API
|
|
||||||
-export([current_time/0]).
|
|
||||||
-export([json_data/1, json_error/2]).
|
|
||||||
|
|
||||||
-spec current_time() -> integer().
|
|
||||||
current_time() ->
|
|
||||||
{Mega, Seconds, _Micro} = os:timestamp(),
|
|
||||||
Mega * 1000000 + Seconds.
|
|
||||||
|
|
||||||
json_data(Data) ->
|
|
||||||
Json = jiffy:encode(#{<<"result">> => Data}, [force_utf8]),
|
|
||||||
iolist_to_binary(Json).
|
|
||||||
|
|
||||||
json_error(ErrCode, ErrMessage) when is_integer(ErrCode), is_binary(ErrMessage) ->
|
|
||||||
jiffy:encode(#{
|
|
||||||
<<"error">> => #{
|
|
||||||
<<"code">> => ErrCode,
|
|
||||||
<<"message">> => ErrMessage
|
|
||||||
}
|
|
||||||
}, [force_utf8]).
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
%%%-------------------------------------------------------------------
|
|
||||||
%%% @author anlicheng
|
|
||||||
%%% @copyright (C) 2025, <COMPANY>
|
|
||||||
%%% @doc
|
|
||||||
%%%
|
|
||||||
%%% @end
|
|
||||||
%%% Created : 07. 4月 2025 14:33
|
|
||||||
%%%-------------------------------------------------------------------
|
|
||||||
-module(mnesia_device_token).
|
|
||||||
-author("anlicheng").
|
|
||||||
-include("dimension_tables.hrl").
|
|
||||||
|
|
||||||
%% API
|
|
||||||
-export([create_table/0, insert/3, get_token/1]).
|
|
||||||
|
|
||||||
create_table() ->
|
|
||||||
%% id生成器
|
|
||||||
mnesia:create_table(device_token, [
|
|
||||||
{attributes, record_info(fields, device_token)},
|
|
||||||
{record_name, device_token},
|
|
||||||
{disc_copies, [node()]},
|
|
||||||
{type, set}
|
|
||||||
]).
|
|
||||||
|
|
||||||
-spec insert(UserId :: binary(), DeviceToken :: binary(), Timestamp :: integer()) -> ok | {error, Reason :: any()}.
|
|
||||||
insert(UserId, DeviceToken, Timestamp) when is_binary(UserId), is_binary(DeviceToken), is_integer(Timestamp) ->
|
|
||||||
Record = #device_token{user_id = UserId, token = DeviceToken, timestamp = Timestamp},
|
|
||||||
case mnesia:transaction(fun() -> mnesia:write(device_token, Record, write) end) of
|
|
||||||
{'atomic', Res} ->
|
|
||||||
Res;
|
|
||||||
{'aborted', Reason} ->
|
|
||||||
{error, Reason}
|
|
||||||
end.
|
|
||||||
|
|
||||||
-spec get_token(UserId :: binary()) -> error | {ok, Token :: binary()}.
|
|
||||||
get_token(UserId) when is_binary(UserId) ->
|
|
||||||
case mnesia:dirty_read(device_token, UserId) of
|
|
||||||
[] ->
|
|
||||||
error;
|
|
||||||
[#device_token{token = Token} | _] ->
|
|
||||||
{ok, Token}
|
|
||||||
end.
|
|
||||||
@ -3,14 +3,17 @@
|
|||||||
|
|
||||||
%% http服务器
|
%% http服务器
|
||||||
{http_server, [
|
{http_server, [
|
||||||
{port, 18084},
|
{port, 18080},
|
||||||
{acceptors, 500},
|
{acceptors, 500},
|
||||||
{max_connections, 10240},
|
{max_connections, 10240},
|
||||||
{backlog, 10240}
|
{backlog, 10240}
|
||||||
]},
|
]},
|
||||||
|
|
||||||
%% 推送配置
|
{pools, [
|
||||||
{apns, [
|
%% 推送设置
|
||||||
|
{apns_pool,
|
||||||
|
[{size, 1}, {max_overflow, 1}, {worker_module, dimension_apn_worker}],
|
||||||
|
[
|
||||||
{connection_opts, [
|
{connection_opts, [
|
||||||
{apple_host, "api.sandbox.push.apple.com"},
|
{apple_host, "api.sandbox.push.apple.com"},
|
||||||
{apple_port, 443},
|
{apple_port, 443},
|
||||||
@ -25,9 +28,8 @@
|
|||||||
{apns_topic, "com.jihe.dimensionhub"},
|
{apns_topic, "com.jihe.dimensionhub"},
|
||||||
{apns_push_type, "alert"}
|
{apns_push_type, "alert"}
|
||||||
]}
|
]}
|
||||||
]},
|
]
|
||||||
|
}
|
||||||
{pools, [
|
|
||||||
|
|
||||||
]}
|
]}
|
||||||
]},
|
]},
|
||||||
|
|||||||
@ -2,9 +2,5 @@
|
|||||||
|
|
||||||
-setcookie dimension_apn_cookie
|
-setcookie dimension_apn_cookie
|
||||||
|
|
||||||
-mnesia dir '"/usr/local/var/mnesia/dimension"'
|
|
||||||
-mnesia dump_log_write_threshold 5000
|
|
||||||
-mnesia dc_dump_limit 40
|
|
||||||
|
|
||||||
+K true
|
+K true
|
||||||
+A30
|
+A30
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user