first workable
This commit is contained in:
parent
fcb5ac6df3
commit
6245fb4aa9
|
@ -12,6 +12,7 @@
|
||||||
terminate/2]).
|
terminate/2]).
|
||||||
|
|
||||||
-include("emqtt.hrl").
|
-include("emqtt.hrl").
|
||||||
|
-include("emqtt_frame.hrl").
|
||||||
|
|
||||||
-define(CLIENT_ID_MAXLEN, 23).
|
-define(CLIENT_ID_MAXLEN, 23).
|
||||||
|
|
||||||
|
@ -53,6 +54,7 @@ handle_call({go, Sock}, _From, _State) ->
|
||||||
inet_error, fun () -> emqtt_net:tune_buffer_size(Sock) end),
|
inet_error, fun () -> emqtt_net:tune_buffer_size(Sock) end),
|
||||||
{ok, ConnStr} = emqtt_net:connection_string(Sock, inbound),
|
{ok, ConnStr} = emqtt_net:connection_string(Sock, inbound),
|
||||||
error_logger:info_msg("accepting MQTT connection (~s)~n", [ConnStr]),
|
error_logger:info_msg("accepting MQTT connection (~s)~n", [ConnStr]),
|
||||||
|
{reply, ok,
|
||||||
control_throttle(
|
control_throttle(
|
||||||
#state{ socket = Sock,
|
#state{ socket = Sock,
|
||||||
conn_name = ConnStr,
|
conn_name = ConnStr,
|
||||||
|
@ -60,13 +62,30 @@ handle_call({go, Sock}, _From, _State) ->
|
||||||
connection_state = running,
|
connection_state = running,
|
||||||
conserve = false,
|
conserve = false,
|
||||||
parse_state = emqtt_frame:initial_state(),
|
parse_state = emqtt_frame:initial_state(),
|
||||||
proc_state = emqtt_processor:initial_state(Sock) }).
|
proc_state = emqtt_processor:initial_state(Sock) })}.
|
||||||
|
|
||||||
handle_cast(Msg, State) ->
|
handle_cast(Msg, State) ->
|
||||||
{stop, {badmsg, Msg}, State}.
|
{stop, {badmsg, Msg}, State}.
|
||||||
|
|
||||||
handle_info({route, Msg}, State) ->
|
handle_info({route, Msg}, #state{proc_state=PState} = State) ->
|
||||||
emqtt_processor:send_client(Msg),
|
#mqtt_msg{ retain = Retain,
|
||||||
|
qos = Qos,
|
||||||
|
topic = Topic,
|
||||||
|
dup = Dup,
|
||||||
|
message_id = MessageId,
|
||||||
|
payload = Payload } = Msg,
|
||||||
|
|
||||||
|
Frame = #mqtt_frame{fixed = #mqtt_frame_fixed{
|
||||||
|
type = ?PUBLISH,
|
||||||
|
qos = Qos,
|
||||||
|
retain = Retain,
|
||||||
|
dup = Dup },
|
||||||
|
variable = #mqtt_frame_publish{
|
||||||
|
topic_name = Topic,
|
||||||
|
message_id = 1},
|
||||||
|
payload = Payload },
|
||||||
|
|
||||||
|
emqtt_processor:send_client(Frame, PState),
|
||||||
{noreply, State};
|
{noreply, State};
|
||||||
|
|
||||||
handle_info({inet_reply, _Ref, ok}, State) ->
|
handle_info({inet_reply, _Ref, ok}, State) ->
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
-module(emqtt_processor).
|
-module(emqtt_processor).
|
||||||
|
|
||||||
-export([info/2, initial_state/1,
|
-export([info/2, initial_state/1,
|
||||||
process_frame/2, send_will/1]).
|
process_frame/2, send_client/2, send_will/1]).
|
||||||
|
|
||||||
-include("emqtt.hrl").
|
-include("emqtt.hrl").
|
||||||
-include("emqtt_frame.hrl").
|
-include("emqtt_frame.hrl").
|
||||||
|
@ -53,11 +53,6 @@ initial_state(Socket) ->
|
||||||
|
|
||||||
info(client_id, #proc_state{ client_id = ClientId }) -> ClientId.
|
info(client_id, #proc_state{ client_id = ClientId }) -> ClientId.
|
||||||
|
|
||||||
process_frame(#mqtt_frame{ fixed = #mqtt_frame_fixed{ type = Type }},
|
|
||||||
PState = #proc_state{ connection = undefined } )
|
|
||||||
when Type =/= ?CONNECT ->
|
|
||||||
{err, connect_expected, PState};
|
|
||||||
|
|
||||||
process_frame(Frame = #mqtt_frame{ fixed = #mqtt_frame_fixed{ type = Type }},
|
process_frame(Frame = #mqtt_frame{ fixed = #mqtt_frame_fixed{ type = Type }},
|
||||||
PState ) ->
|
PState ) ->
|
||||||
process_request(Type, Frame, PState).
|
process_request(Type, Frame, PState).
|
||||||
|
@ -69,6 +64,7 @@ process_request(?CONNECT,
|
||||||
proto_ver = ProtoVersion,
|
proto_ver = ProtoVersion,
|
||||||
clean_sess = CleanSess,
|
clean_sess = CleanSess,
|
||||||
client_id = ClientId } = Var}, PState) ->
|
client_id = ClientId } = Var}, PState) ->
|
||||||
|
error_logger:info_msg("connect frame: ~p~n", [Var]),
|
||||||
{ReturnCode, PState1} =
|
{ReturnCode, PState1} =
|
||||||
case {ProtoVersion =:= ?MQTT_PROTO_MAJOR,
|
case {ProtoVersion =:= ?MQTT_PROTO_MAJOR,
|
||||||
emqtt_util:valid_client_id(ClientId)} of
|
emqtt_util:valid_client_id(ClientId)} of
|
||||||
|
@ -110,7 +106,7 @@ process_request(?PUBLISH,
|
||||||
dup = Dup },
|
dup = Dup },
|
||||||
variable = #mqtt_frame_publish{ topic_name = Topic,
|
variable = #mqtt_frame_publish{ topic_name = Topic,
|
||||||
message_id = MessageId },
|
message_id = MessageId },
|
||||||
payload = Payload }, PState) ->
|
payload = Payload }, #proc_state{ message_id = MsgId } = PState) ->
|
||||||
Msg = #mqtt_msg{ retain = Retain,
|
Msg = #mqtt_msg{ retain = Retain,
|
||||||
qos = Qos,
|
qos = Qos,
|
||||||
topic = Topic,
|
topic = Topic,
|
||||||
|
@ -121,7 +117,7 @@ process_request(?PUBLISH,
|
||||||
|
|
||||||
send_client(
|
send_client(
|
||||||
#mqtt_frame{ fixed = #mqtt_frame_fixed{ type = ?PUBACK },
|
#mqtt_frame{ fixed = #mqtt_frame_fixed{ type = ?PUBACK },
|
||||||
variable = #mqtt_frame_publish{ message_id = MessageId }},
|
variable = #mqtt_frame_publish{ message_id = MsgId}},
|
||||||
PState),
|
PState),
|
||||||
{ok, PState};
|
{ok, PState};
|
||||||
|
|
||||||
|
@ -141,7 +137,7 @@ process_request(?SUBSCRIBE,
|
||||||
|
|
||||||
[emqtt_topic:insert(Name) || #mqtt_topic{name=Name} <- Topics],
|
[emqtt_topic:insert(Name) || #mqtt_topic{name=Name} <- Topics],
|
||||||
|
|
||||||
[emqtt_router:insert(#subscriber{topic=Name, pid=self()})
|
[emqtt_router:insert(#subscriber{topic=emqtt_util:binary(Name), pid=self()})
|
||||||
|| #mqtt_topic{name=Name} <- Topics],
|
|| #mqtt_topic{name=Name} <- Topics],
|
||||||
|
|
||||||
send_client(#mqtt_frame{ fixed = #mqtt_frame_fixed{ type = ?SUBACK },
|
send_client(#mqtt_frame{ fixed = #mqtt_frame_fixed{ type = ?SUBACK },
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
-module(emqtt_router).
|
-module(emqtt_router).
|
||||||
|
|
||||||
-include("emqtt.hrl").
|
-include("emqtt.hrl").
|
||||||
|
-include("emqtt_frame.hrl").
|
||||||
|
|
||||||
-export([start_link/0]).
|
-export([start_link/0]).
|
||||||
|
|
||||||
-export([route/2,
|
-export([route/1,
|
||||||
|
route/2,
|
||||||
insert/1,
|
insert/1,
|
||||||
delete/1]).
|
delete/1]).
|
||||||
|
|
||||||
|
@ -22,6 +24,16 @@
|
||||||
start_link() ->
|
start_link() ->
|
||||||
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
|
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
|
||||||
|
|
||||||
|
binary(S) when is_list(S) ->
|
||||||
|
list_to_binary(S);
|
||||||
|
|
||||||
|
binary(B) when is_binary(B) ->
|
||||||
|
B.
|
||||||
|
|
||||||
|
route(#mqtt_msg{topic=Topic}=Msg) when is_record(Msg, mqtt_msg) ->
|
||||||
|
error_logger:info_msg("route msg: ~p~n", [Msg]),
|
||||||
|
[ Pid ! {route, Msg} || #subscriber{pid=Pid} <- ets:lookup(subscriber, binary(Topic)) ].
|
||||||
|
|
||||||
route(Topic, Msg) ->
|
route(Topic, Msg) ->
|
||||||
[ Pid ! {route, Msg} || #subscriber{pid=Pid} <- ets:lookup(subscriber, Topic) ].
|
[ Pid ! {route, Msg} || #subscriber{pid=Pid} <- ets:lookup(subscriber, Topic) ].
|
||||||
|
|
||||||
|
@ -32,8 +44,8 @@ delete(Sub) when is_record(Sub, subscriber) ->
|
||||||
gen_server:cast(?MODULE, {delete, Sub}).
|
gen_server:cast(?MODULE, {delete, Sub}).
|
||||||
|
|
||||||
init([]) ->
|
init([]) ->
|
||||||
ets:new(subscriber, [bag, protected, {keypos, 2}]),
|
Res = ets:new(subscriber, [bag, protected, named_table, {keypos, 2}]),
|
||||||
error_logger:info_msg("emqtt_router is started."),
|
error_logger:info_msg("emqtt_router is started: ~p~n", [Res]),
|
||||||
{ok, #state{}}.
|
{ok, #state{}}.
|
||||||
|
|
||||||
handle_call({insert, Sub}, _From, State) ->
|
handle_call({insert, Sub}, _From, State) ->
|
||||||
|
|
|
@ -22,7 +22,8 @@
|
||||||
start_link() ->
|
start_link() ->
|
||||||
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
|
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
|
||||||
|
|
||||||
match(Topic) when is_binary(Topic) ->
|
match(Topic0) ->
|
||||||
|
Topic = emqtt_util:binary(Topic0),
|
||||||
Words = topic_split(Topic),
|
Words = topic_split(Topic),
|
||||||
DirectMatches = mnesia:dirty_read(direct_topic, Words),
|
DirectMatches = mnesia:dirty_read(direct_topic, Words),
|
||||||
WildcardMatches = lists:append([
|
WildcardMatches = lists:append([
|
||||||
|
@ -32,11 +33,11 @@ match(Topic) when is_binary(Topic) ->
|
||||||
]),
|
]),
|
||||||
DirectMatches ++ WildcardMatches.
|
DirectMatches ++ WildcardMatches.
|
||||||
|
|
||||||
insert(Topic) when is_binary(Topic) ->
|
insert(Topic) ->
|
||||||
gen_server:call(?MODULE, {insert, Topic}).
|
gen_server:call(?MODULE, {insert, emqtt_util:binary(Topic)}).
|
||||||
|
|
||||||
delete(Topic) when is_binary(Topic) ->
|
delete(Topic) ->
|
||||||
gen_server:cast(?MODULE, {delete, Topic}).
|
gen_server:cast(?MODULE, {delete, emqtt_util:binary(Topic)}).
|
||||||
|
|
||||||
init([]) ->
|
init([]) ->
|
||||||
{atomic, ok} = mnesia:create_table(
|
{atomic, ok} = mnesia:create_table(
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
|
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
|
|
||||||
|
binary(L) when is_list(L) -> list_to_binary(L);
|
||||||
|
binary(B) when is_binary(B) -> B.
|
||||||
|
|
||||||
subcription_queue_name(ClientId) ->
|
subcription_queue_name(ClientId) ->
|
||||||
Base = "mqtt-subscription-" ++ ClientId ++ "qos",
|
Base = "mqtt-subscription-" ++ ClientId ++ "qos",
|
||||||
{list_to_binary(Base ++ "0"), list_to_binary(Base ++ "1")}.
|
{list_to_binary(Base ++ "0"), list_to_binary(Base ++ "1")}.
|
||||||
|
|
Loading…
Reference in New Issue