Handle will message correctly
This commit is contained in:
parent
cff120c6d0
commit
f3a92f35f6
|
@ -87,7 +87,8 @@
|
||||||
alive_timer => keepalive,
|
alive_timer => keepalive,
|
||||||
retry_timer => retry_delivery,
|
retry_timer => retry_delivery,
|
||||||
await_timer => expire_awaiting_rel,
|
await_timer => expire_awaiting_rel,
|
||||||
expire_timer => expire_session
|
expire_timer => expire_session,
|
||||||
|
will_timer => will_message
|
||||||
}).
|
}).
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
@ -342,16 +343,18 @@ handle_in(?DISCONNECT_PACKET(RC, Properties), Channel = #channel{session = Sessi
|
||||||
_ -> Channel#channel{session = emqx_session:update_expiry_interval(Interval, Session)}
|
_ -> Channel#channel{session = emqx_session:update_expiry_interval(Interval, Session)}
|
||||||
end),
|
end),
|
||||||
case Interval of
|
case Interval of
|
||||||
?UINT_MAX -> {ok, NChannel};
|
?UINT_MAX ->
|
||||||
Int when Int > 0 -> {ok, ensure_timer(expire_timer, NChannel)};
|
{ok, ensure_timer(will_timer, NChannel)};
|
||||||
|
Int when Int > 0 ->
|
||||||
|
{ok, ensure_timer([will_timer, expire_timer], NChannel)};
|
||||||
_Other ->
|
_Other ->
|
||||||
Reason = case RC of
|
Reason = case RC of
|
||||||
?RC_SUCCESS -> closed;
|
?RC_SUCCESS -> normal;
|
||||||
_ ->
|
_ ->
|
||||||
Ver = emqx_protocol:info(proto_ver, Protocol),
|
Ver = emqx_protocol:info(proto_ver, Protocol),
|
||||||
emqx_reason_codes:name(RC, Ver)
|
emqx_reason_codes:name(RC, Ver)
|
||||||
end,
|
end,
|
||||||
{stop, {shutdown, Reason}, Channel}
|
{stop, {shutdown, Reason}, NChannel}
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -680,9 +683,14 @@ timeout(TRef, expire_awaiting_rel, Channel = #channel{session = Session,
|
||||||
{ok, reset_timer(await_timer, Timeout, Channel#channel{session = Session})}
|
{ok, reset_timer(await_timer, Timeout, Channel#channel{session = Session})}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
timeout(_TRef, expire_session, Channel) ->
|
timeout(TRef, expire_session, Channel = #channel{timers = #{expire_timer := TRef}}) ->
|
||||||
shutdown(expired, Channel);
|
shutdown(expired, Channel);
|
||||||
|
|
||||||
|
timeout(TRef, will_message, Channel = #channel{protocol = Protocol,
|
||||||
|
timers = #{will_timer := TRef}}) ->
|
||||||
|
publish_will_msg(emqx_protocol:info(will_msg, Protocol)),
|
||||||
|
{ok, clean_timer(will_timer, Channel#channel{protocol = emqx_protocol:clear_will_msg(Protocol)})};
|
||||||
|
|
||||||
timeout(_TRef, Msg, Channel) ->
|
timeout(_TRef, Msg, Channel) ->
|
||||||
?LOG(error, "Unexpected timeout: ~p~n", [Msg]),
|
?LOG(error, "Unexpected timeout: ~p~n", [Msg]),
|
||||||
{ok, Channel}.
|
{ok, Channel}.
|
||||||
|
@ -691,6 +699,11 @@ timeout(_TRef, Msg, Channel) ->
|
||||||
%% Ensure timers
|
%% Ensure timers
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
ensure_timer([Name], Channel) ->
|
||||||
|
ensure_timer(Name, Channel);
|
||||||
|
ensure_timer([Name | Rest], Channel) ->
|
||||||
|
ensure_timer(Rest, ensure_timer(Name, Channel));
|
||||||
|
|
||||||
ensure_timer(Name, Channel = #channel{timers = Timers}) ->
|
ensure_timer(Name, Channel = #channel{timers = Timers}) ->
|
||||||
TRef = maps:get(Name, Timers, undefined),
|
TRef = maps:get(Name, Timers, undefined),
|
||||||
Time = interval(Name, Channel),
|
Time = interval(Name, Channel),
|
||||||
|
@ -723,7 +736,9 @@ interval(retry_timer, #channel{session = Session}) ->
|
||||||
interval(await_timer, #channel{session = Session}) ->
|
interval(await_timer, #channel{session = Session}) ->
|
||||||
emqx_session:info(await_rel_timeout, Session);
|
emqx_session:info(await_rel_timeout, Session);
|
||||||
interval(expire_timer, #channel{session = Session}) ->
|
interval(expire_timer, #channel{session = Session}) ->
|
||||||
timer:seconds(emqx_session:info(expiry_interval, Session)).
|
timer:seconds(emqx_session:info(expiry_interval, Session));
|
||||||
|
interval(will_timer, #channel{protocol = Protocol}) ->
|
||||||
|
timer:seconds(emqx_protocol:info(will_delay_interval, Protocol)).
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Terminate
|
%% Terminate
|
||||||
|
|
|
@ -59,13 +59,22 @@
|
||||||
-spec(init(#mqtt_packet_connect{}) -> protocol()).
|
-spec(init(#mqtt_packet_connect{}) -> protocol()).
|
||||||
init(#mqtt_packet_connect{proto_name = ProtoName,
|
init(#mqtt_packet_connect{proto_name = ProtoName,
|
||||||
proto_ver = ProtoVer,
|
proto_ver = ProtoVer,
|
||||||
|
will_props = WillProps,
|
||||||
clean_start = CleanStart,
|
clean_start = CleanStart,
|
||||||
keepalive = Keepalive,
|
keepalive = Keepalive,
|
||||||
properties = Properties,
|
properties = Properties,
|
||||||
client_id = ClientId,
|
client_id = ClientId,
|
||||||
username = Username
|
username = Username
|
||||||
} = ConnPkt) ->
|
} = ConnPkt) ->
|
||||||
WillMsg = emqx_packet:will_msg(ConnPkt),
|
WillMsg = emqx_packet:will_msg(
|
||||||
|
case ProtoVer of
|
||||||
|
?MQTT_PROTO_V5 ->
|
||||||
|
WillDelayInterval = get_property('Will-Delay-Interval', WillProps, 0),
|
||||||
|
ConnPkt#mqtt_packet_connect{
|
||||||
|
will_props = set_property('Will-Delay-Interval', WillDelayInterval, WillProps)};
|
||||||
|
_ ->
|
||||||
|
ConnPkt
|
||||||
|
end),
|
||||||
#protocol{proto_name = ProtoName,
|
#protocol{proto_name = ProtoName,
|
||||||
proto_ver = ProtoVer,
|
proto_ver = ProtoVer,
|
||||||
clean_start = CleanStart,
|
clean_start = CleanStart,
|
||||||
|
@ -110,6 +119,8 @@ info(username, #protocol{username = Username}) ->
|
||||||
Username;
|
Username;
|
||||||
info(will_msg, #protocol{will_msg = WillMsg}) ->
|
info(will_msg, #protocol{will_msg = WillMsg}) ->
|
||||||
WillMsg;
|
WillMsg;
|
||||||
|
info(will_delay_interval, #protocol{will_msg = WillMsg}) ->
|
||||||
|
emqx_message:get_header('Will-Delay-Interval', WillMsg, 0);
|
||||||
info(conn_props, #protocol{conn_props = ConnProps}) ->
|
info(conn_props, #protocol{conn_props = ConnProps}) ->
|
||||||
ConnProps;
|
ConnProps;
|
||||||
info(topic_aliases, #protocol{topic_aliases = Aliases}) ->
|
info(topic_aliases, #protocol{topic_aliases = Aliases}) ->
|
||||||
|
@ -137,3 +148,13 @@ save_alias(AliasId, Topic, Protocol = #protocol{topic_aliases = Aliases}) ->
|
||||||
|
|
||||||
clear_will_msg(Protocol) ->
|
clear_will_msg(Protocol) ->
|
||||||
Protocol#protocol{will_msg = undefined}.
|
Protocol#protocol{will_msg = undefined}.
|
||||||
|
|
||||||
|
set_property(Name, Value, undefined) ->
|
||||||
|
#{Name => Value};
|
||||||
|
set_property(Name, Value, Props) ->
|
||||||
|
Props#{Name => Value}.
|
||||||
|
|
||||||
|
get_property(_Name, undefined, Default) ->
|
||||||
|
Default;
|
||||||
|
get_property(Name, Props, Default) ->
|
||||||
|
maps:get(Name, Props, Default).
|
||||||
|
|
Loading…
Reference in New Issue