From cc86c959510e27a196db3fffad7367f2a69e68b3 Mon Sep 17 00:00:00 2001 From: Ery Lee Date: Thu, 5 Mar 2015 14:43:32 +0800 Subject: [PATCH] fix issue #58, add emqtt_opts:merge/2 --- apps/emqtt/src/emqtt.erl | 69 +++++++++++++++------------- apps/emqtt/src/emqtt_app.erl | 2 +- apps/emqtt/src/emqtt_opts.erl | 47 +++++++++++++++++++ apps/emqtt/test/emqtt_opts_tests.erl | 58 +++++++++++++++++++++++ 4 files changed, 144 insertions(+), 32 deletions(-) create mode 100644 apps/emqtt/src/emqtt_opts.erl create mode 100644 apps/emqtt/test/emqtt_opts_tests.erl diff --git a/apps/emqtt/src/emqtt.erl b/apps/emqtt/src/emqtt.erl index 0ed219bfc..38134e7cf 100644 --- a/apps/emqtt/src/emqtt.erl +++ b/apps/emqtt/src/emqtt.erl @@ -1,28 +1,32 @@ -%%----------------------------------------------------------------------------- -%% Copyright (c) 2012-2015, Feng Lee -%% -%% Permission is hereby granted, free of charge, to any person obtaining a copy -%% of this software and associated documentation files (the "Software"), to deal -%% in the Software without restriction, including without limitation the rights -%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -%% copies of the Software, and to permit persons to whom the Software is -%% furnished to do so, subject to the following conditions: -%% -%% The above copyright notice and this permission notice shall be included in all -%% copies or substantial portions of the Software. -%% -%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -%% SOFTWARE. -%%------------------------------------------------------------------------------ - +%%%----------------------------------------------------------------------------- +%%% @Copyright (C) 2012-2015, Feng Lee +%%% +%%% Permission is hereby granted, free of charge, to any person obtaining a copy +%%% of this software and associated documentation files (the "Software"), to deal +%%% in the Software without restriction, including without limitation the rights +%%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +%%% copies of the Software, and to permit persons to whom the Software is +%%% furnished to do so, subject to the following conditions: +%%% +%%% The above copyright notice and this permission notice shall be included in all +%%% copies or substantial portions of the Software. +%%% +%%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +%%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +%%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +%%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +%%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +%%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +%%% SOFTWARE. +%%%----------------------------------------------------------------------------- +%%% @doc +%%% emqtt main module. +%%% +%%% @end +%%%----------------------------------------------------------------------------- -module(emqtt). --export([listen/1]). +-export([start/0, open/1]). -define(MQTT_SOCKOPTS, [ binary, @@ -32,19 +36,22 @@ {nodelay, true} ]). -listen(Listeners) when is_list(Listeners) -> - [listen(Listener) || Listener <- Listeners]; +-spec start() -> ok | {error, any()}. +start() -> + application:start(emqtt). -listen({mqtt, Port, Options}) -> +open(Listeners) when is_list(Listeners) -> + [open(Listener) || Listener <- Listeners]; + +open({mqtt, Port, Options}) -> MFArgs = {emqtt_client, start_link, []}, - esockd:open(mqtt, Port, Options ++ ?MQTT_SOCKOPTS, MFArgs); + esockd:open(mqtt, Port, emqtt_opts:merge(?MQTT_SOCKOPTS, Options) , MFArgs); -listen({mqtts, Port, Options}) -> +open({mqtts, Port, Options}) -> MFArgs = {emqtt_client, start_link, []}, - esockd:open(mqtts, Port, Options ++ ?MQTT_SOCKOPTS, MFArgs); + esockd:open(mqtts, Port, emqtt_opts:merge(?MQTT_SOCKOPTS, Options) , MFArgs); -listen({http, Port, Options}) -> +open({http, Port, Options}) -> MFArgs = {emqtt_http, handle, []}, mochiweb:start_http(Port, Options, MFArgs). - diff --git a/apps/emqtt/src/emqtt_app.erl b/apps/emqtt/src/emqtt_app.erl index 82f4bd366..2b282e9a5 100644 --- a/apps/emqtt/src/emqtt_app.erl +++ b/apps/emqtt/src/emqtt_app.erl @@ -45,7 +45,7 @@ start(_StartType, _StartArgs) -> {ok, Sup} = emqtt_sup:start_link(), start_servers(Sup), {ok, Listeners} = application:get_env(listen), - emqtt:listen(Listeners), + emqtt:open(Listeners), register(emqtt, self()), print_vsn(), {ok, Sup}. diff --git a/apps/emqtt/src/emqtt_opts.erl b/apps/emqtt/src/emqtt_opts.erl new file mode 100644 index 000000000..dae0a60d2 --- /dev/null +++ b/apps/emqtt/src/emqtt_opts.erl @@ -0,0 +1,47 @@ +%%%----------------------------------------------------------------------------- +%%% @Copyright (C) 2012-2015, Feng Lee +%%% +%%% Permission is hereby granted, free of charge, to any person obtaining a copy +%%% of this software and associated documentation files (the "Software"), to deal +%%% in the Software without restriction, including without limitation the rights +%%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +%%% copies of the Software, and to permit persons to whom the Software is +%%% furnished to do so, subject to the following conditions: +%%% +%%% The above copyright notice and this permission notice shall be included in all +%%% copies or substantial portions of the Software. +%%% +%%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +%%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +%%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +%%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +%%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +%%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +%%% SOFTWARE. +%%%----------------------------------------------------------------------------- +%%% @doc +%%% emqtt options handler. +%%% +%%% @end +%%%----------------------------------------------------------------------------- +-module(emqtt_opts). + +-export([merge/2]). + +merge(Defaults, Options) -> + lists:foldl( + fun({Opt, Val}, Acc) -> + case lists:keymember(Opt, 1, Acc) of + true -> + lists:keyreplace(Opt, 1, Acc, {Opt, Val}); + false -> + [{Opt, Val}|Acc] + end; + (Opt, Acc) -> + case lists:member(Opt, Acc) of + true -> Acc; + false -> [Opt | Acc] + end + end, Defaults, Options). + + diff --git a/apps/emqtt/test/emqtt_opts_tests.erl b/apps/emqtt/test/emqtt_opts_tests.erl new file mode 100644 index 000000000..84c274841 --- /dev/null +++ b/apps/emqtt/test/emqtt_opts_tests.erl @@ -0,0 +1,58 @@ +%%%----------------------------------------------------------------------------- +%%% @Copyright (C) 2012-2015, Feng Lee +%%% +%%% Permission is hereby granted, free of charge, to any person obtaining a copy +%%% of this software and associated documentation files (the "Software"), to deal +%%% in the Software without restriction, including without limitation the rights +%%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +%%% copies of the Software, and to permit persons to whom the Software is +%%% furnished to do so, subject to the following conditions: +%%% +%%% The above copyright notice and this permission notice shall be included in all +%%% copies or substantial portions of the Software. +%%% +%%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +%%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +%%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +%%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +%%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +%%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +%%% SOFTWARE. +%%%----------------------------------------------------------------------------- +%%% @doc +%%% emqtt_opts_tests. +%%% +%%% @end +%%%----------------------------------------------------------------------------- +-module(emqtt_opts_tests). + +-ifdef(TEST). + +-include_lib("eunit/include/eunit.hrl"). + +-define(SOCKOPTS, [ + binary, + {packet, raw}, + {reuseaddr, true}, + {backlog, 512}, + {nodelay, true} +]). + +merge_test() -> + Opts = emqtt_opts:merge(?SOCKOPTS, [raw, + {backlog, 1024}, + {nodelay, false}, + {max_clients, 1024}, + {acceptor_pool, 4}]), + ?assertEqual(1024, proplists:get_value(backlog, Opts)), + ?assertEqual(1024, proplists:get_value(max_clients, Opts)), + ?assertEqual(lists:sort(Opts), [binary, raw, + {acceptor_pool,4}, + {backlog,1024}, + {max_clients,1024}, + {nodelay,false}, + {packet,raw}, + {reuseaddr,true}]). + + +-endif.