%%%------------------------------------------------------------------- %% @doc iot public API %% @end %%%------------------------------------------------------------------- -module(iot_app). -behaviour(application). -export([start/2, stop/1]). start(_StartType, _StartArgs) -> ok = iot_log:set_metadata(), io:setopts([{encoding, unicode}]), %% 加速内存的回收 erlang:system_flag(fullsweep_after, 16), try %% 启动并校验已经初始化好的 mnesia 数据库 ok = iot_mnesia:start() catch Class:Reason:Stack -> logger:warning("[iot_app] start failed, class: ~p, reason: ~p, stack: ~p", [Class, Reason, Stack]) end, %% 启动http服务。当前 supervisor 初始化依赖本机 simulator API,因此保留此顺序。 start_http_server(), %% 启动ssl服务 start_ssl_server(), iot_sup:start_link(). stop(_State) -> stop_started_services(), ok. %% internal functions start_http_server() -> {ok, Props} = application:get_env(iot, http_server), Acceptors = proplists:get_value(acceptors, Props, 50), MaxConnections = proplists:get_value(max_connections, Props, 10240), Backlog = proplists:get_value(backlog, Props, 1024), Port = proplists:get_value(port, Props), Dispatcher = cowboy_router:compile([ {'_', [ {"/host/[...]", http_protocol, [host_handler]}, {"/container/[...]", http_protocol, [container_handler]}, {"/endpoint/[...]", http_protocol, [endpoint_handler]}, {"/simulator/[...]", http_protocol, [simulator_api_handler]}, {"/event_stream", event_stream_handler, []} ]} ]), TransOpts = #{ max_connections => MaxConnections, num_acceptors => Acceptors, shutdown => brutal_kill, socket_opts => [ {backlog, Backlog}, {port, Port} ] }, {ok, Pid} = cowboy:start_clear(http_listener, TransOpts, #{env => #{dispatch => Dispatcher}}), logger:debug("[http_server] the http server start at: ~p, pid is: ~p", [Port, Pid]). %% 启动ssl服务 start_ssl_server() -> {ok, Props} = application:get_env(iot, ssl_server), Acceptors = proplists:get_value(acceptors, Props, 50), MaxConnections = proplists:get_value(max_connections, Props, 10240), Backlog = proplists:get_value(backlog, Props, 1024), Port = proplists:get_value(port, Props), PrivDir = code:priv_dir(iot), CertFile = filename:join([PrivDir, "ssl", "server.crt"]), KeyFile = filename:join([PrivDir, "ssl", "server.key"]), TransOpts = #{ max_connections => MaxConnections, num_acceptors => Acceptors, shutdown => brutal_kill, socket_opts => [ {nodelay, true}, {backlog, Backlog}, {port, Port}, {certfile, CertFile}, {keyfile, KeyFile} ] }, {ok, _} = ranch:start_listener(ssl_server, ranch_ssl, TransOpts, ssl_channel, []), logger:debug("[iot_app] the ssl server start at: ~p", [Port]). stop_started_services() -> _ = cowboy:stop_listener(http_listener), _ = ranch:stop_listener(ssl_server), _ = iot_mnesia:stop(), ok.