Make send method configurable and export useful functions
Needed for the new Web-MQTT plugin.
This commit is contained in:
parent
9ba1da7434
commit
1f1cb7ab9b
|
|
@ -45,7 +45,8 @@
|
||||||
%% Retained messages handler. See rabbit_mqtt_retainer_sup
|
%% Retained messages handler. See rabbit_mqtt_retainer_sup
|
||||||
%% and rabbit_mqtt_retainer.
|
%% and rabbit_mqtt_retainer.
|
||||||
retainer_pid,
|
retainer_pid,
|
||||||
auth_state}).
|
auth_state,
|
||||||
|
send_fun}).
|
||||||
|
|
||||||
-record(auth_state, {username,
|
-record(auth_state, {username,
|
||||||
user,
|
user,
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
-module(rabbit_mqtt_processor).
|
-module(rabbit_mqtt_processor).
|
||||||
|
|
||||||
-export([info/2, initial_state/2,
|
-export([info/2, initial_state/2, initial_state/3,
|
||||||
process_frame/2, amqp_pub/2, amqp_callback/2, send_will/1,
|
process_frame/2, amqp_pub/2, amqp_callback/2, send_will/1,
|
||||||
close_connection/1]).
|
close_connection/1]).
|
||||||
|
|
||||||
|
|
@ -32,6 +32,9 @@
|
||||||
Frame = #mqtt_frame{ fixed = #mqtt_frame_fixed{ type = Type }}).
|
Frame = #mqtt_frame{ fixed = #mqtt_frame_fixed{ type = Type }}).
|
||||||
|
|
||||||
initial_state(Socket,SSLLoginName) ->
|
initial_state(Socket,SSLLoginName) ->
|
||||||
|
initial_state(Socket, SSLLoginName, fun send_client/2).
|
||||||
|
|
||||||
|
initial_state(Socket,SSLLoginName,SendFun) ->
|
||||||
#proc_state{ unacked_pubs = gb_trees:empty(),
|
#proc_state{ unacked_pubs = gb_trees:empty(),
|
||||||
awaiting_ack = gb_trees:empty(),
|
awaiting_ack = gb_trees:empty(),
|
||||||
message_id = 1,
|
message_id = 1,
|
||||||
|
|
@ -40,7 +43,8 @@ initial_state(Socket,SSLLoginName) ->
|
||||||
channels = {undefined, undefined},
|
channels = {undefined, undefined},
|
||||||
exchange = rabbit_mqtt_util:env(exchange),
|
exchange = rabbit_mqtt_util:env(exchange),
|
||||||
socket = Socket,
|
socket = Socket,
|
||||||
ssl_login_name = SSLLoginName }.
|
ssl_login_name = SSLLoginName,
|
||||||
|
send_fun = SendFun }.
|
||||||
|
|
||||||
info(client_id, #proc_state{ client_id = ClientId }) -> ClientId.
|
info(client_id, #proc_state{ client_id = ClientId }) -> ClientId.
|
||||||
|
|
||||||
|
|
@ -60,7 +64,8 @@ process_request(?CONNECT,
|
||||||
clean_sess = CleanSess,
|
clean_sess = CleanSess,
|
||||||
client_id = ClientId0,
|
client_id = ClientId0,
|
||||||
keep_alive = Keepalive} = Var},
|
keep_alive = Keepalive} = Var},
|
||||||
PState = #proc_state{ ssl_login_name = SSLLoginName }) ->
|
PState = #proc_state{ ssl_login_name = SSLLoginName,
|
||||||
|
send_fun = SendFun }) ->
|
||||||
ClientId = case ClientId0 of
|
ClientId = case ClientId0 of
|
||||||
[] -> rabbit_mqtt_util:gen_client_id();
|
[] -> rabbit_mqtt_util:gen_client_id();
|
||||||
[_|_] -> ClientId0
|
[_|_] -> ClientId0
|
||||||
|
|
@ -106,7 +111,7 @@ process_request(?CONNECT,
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
send_client(#mqtt_frame{ fixed = #mqtt_frame_fixed{ type = ?CONNACK},
|
SendFun(#mqtt_frame{ fixed = #mqtt_frame_fixed{ type = ?CONNACK},
|
||||||
variable = #mqtt_frame_connack{
|
variable = #mqtt_frame_connack{
|
||||||
return_code = ReturnCode }}, PState1),
|
return_code = ReturnCode }}, PState1),
|
||||||
{ok, PState1};
|
{ok, PState1};
|
||||||
|
|
@ -162,7 +167,8 @@ process_request(?SUBSCRIBE,
|
||||||
payload = undefined},
|
payload = undefined},
|
||||||
#proc_state{channels = {Channel, _},
|
#proc_state{channels = {Channel, _},
|
||||||
exchange = Exchange,
|
exchange = Exchange,
|
||||||
retainer_pid = RPid} = PState0) ->
|
retainer_pid = RPid,
|
||||||
|
send_fun = SendFun } = PState0) ->
|
||||||
check_subscribe_or_die(Topics, fun() ->
|
check_subscribe_or_die(Topics, fun() ->
|
||||||
{QosResponse, PState1} =
|
{QosResponse, PState1} =
|
||||||
lists:foldl(fun (#mqtt_topic{name = TopicName,
|
lists:foldl(fun (#mqtt_topic{name = TopicName,
|
||||||
|
|
@ -180,7 +186,7 @@ process_request(?SUBSCRIBE,
|
||||||
PState1 #proc_state{subscriptions =
|
PState1 #proc_state{subscriptions =
|
||||||
dict:append(TopicName, SupportedQos, Subs)}}
|
dict:append(TopicName, SupportedQos, Subs)}}
|
||||||
end, {[], PState0}, Topics),
|
end, {[], PState0}, Topics),
|
||||||
send_client(#mqtt_frame{fixed = #mqtt_frame_fixed{type = ?SUBACK},
|
SendFun(#mqtt_frame{fixed = #mqtt_frame_fixed{type = ?SUBACK},
|
||||||
variable = #mqtt_frame_suback{
|
variable = #mqtt_frame_suback{
|
||||||
message_id = MessageId,
|
message_id = MessageId,
|
||||||
qos_table = QosResponse}}, PState1),
|
qos_table = QosResponse}}, PState1),
|
||||||
|
|
@ -203,7 +209,8 @@ process_request(?UNSUBSCRIBE,
|
||||||
payload = undefined }, #proc_state{ channels = {Channel, _},
|
payload = undefined }, #proc_state{ channels = {Channel, _},
|
||||||
exchange = Exchange,
|
exchange = Exchange,
|
||||||
client_id = ClientId,
|
client_id = ClientId,
|
||||||
subscriptions = Subs0} = PState) ->
|
subscriptions = Subs0,
|
||||||
|
send_fun = SendFun } = PState) ->
|
||||||
Queues = rabbit_mqtt_util:subcription_queue_name(ClientId),
|
Queues = rabbit_mqtt_util:subcription_queue_name(ClientId),
|
||||||
Subs1 =
|
Subs1 =
|
||||||
lists:foldl(
|
lists:foldl(
|
||||||
|
|
@ -224,13 +231,13 @@ process_request(?UNSUBSCRIBE,
|
||||||
end, QosSubs),
|
end, QosSubs),
|
||||||
dict:erase(TopicName, Subs)
|
dict:erase(TopicName, Subs)
|
||||||
end, Subs0, Topics),
|
end, Subs0, Topics),
|
||||||
send_client(#mqtt_frame{ fixed = #mqtt_frame_fixed { type = ?UNSUBACK },
|
SendFun(#mqtt_frame{ fixed = #mqtt_frame_fixed { type = ?UNSUBACK },
|
||||||
variable = #mqtt_frame_suback{ message_id = MessageId }},
|
variable = #mqtt_frame_suback{ message_id = MessageId }},
|
||||||
PState),
|
PState),
|
||||||
{ok, PState #proc_state{ subscriptions = Subs1 }};
|
{ok, PState #proc_state{ subscriptions = Subs1 }};
|
||||||
|
|
||||||
process_request(?PINGREQ, #mqtt_frame{}, PState) ->
|
process_request(?PINGREQ, #mqtt_frame{}, #proc_state{ send_fun = SendFun } = PState) ->
|
||||||
send_client(#mqtt_frame{ fixed = #mqtt_frame_fixed{ type = ?PINGRESP }},
|
SendFun(#mqtt_frame{ fixed = #mqtt_frame_fixed{ type = ?PINGRESP }},
|
||||||
PState),
|
PState),
|
||||||
{ok, PState};
|
{ok, PState};
|
||||||
|
|
||||||
|
|
@ -246,7 +253,8 @@ hand_off_to_retainer(RetainerPid, Topic, Msg) ->
|
||||||
rabbit_mqtt_retainer:retain(RetainerPid, Topic, Msg),
|
rabbit_mqtt_retainer:retain(RetainerPid, Topic, Msg),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
maybe_send_retained_message(RPid, #mqtt_topic{name = S, qos = SubscribeQos}, MsgId, PState) ->
|
maybe_send_retained_message(RPid, #mqtt_topic{name = S, qos = SubscribeQos}, MsgId,
|
||||||
|
#proc_state{ send_fun = SendFun } = PState) ->
|
||||||
case rabbit_mqtt_retainer:fetch(RPid, S) of
|
case rabbit_mqtt_retainer:fetch(RPid, S) of
|
||||||
undefined -> false;
|
undefined -> false;
|
||||||
Msg ->
|
Msg ->
|
||||||
|
|
@ -258,7 +266,7 @@ maybe_send_retained_message(RPid, #mqtt_topic{name = S, qos = SubscribeQos}, Msg
|
||||||
?QOS_0 -> undefined;
|
?QOS_0 -> undefined;
|
||||||
?QOS_1 -> MsgId
|
?QOS_1 -> MsgId
|
||||||
end,
|
end,
|
||||||
send_client(#mqtt_frame{fixed = #mqtt_frame_fixed{
|
SendFun(#mqtt_frame{fixed = #mqtt_frame_fixed{
|
||||||
type = ?PUBLISH,
|
type = ?PUBLISH,
|
||||||
qos = Qos,
|
qos = Qos,
|
||||||
dup = false,
|
dup = false,
|
||||||
|
|
@ -282,7 +290,8 @@ amqp_callback({#'basic.deliver'{ consumer_tag = ConsumerTag,
|
||||||
DeliveryCtx} = Delivery,
|
DeliveryCtx} = Delivery,
|
||||||
#proc_state{ channels = {Channel, _},
|
#proc_state{ channels = {Channel, _},
|
||||||
awaiting_ack = Awaiting,
|
awaiting_ack = Awaiting,
|
||||||
message_id = MsgId } = PState) ->
|
message_id = MsgId,
|
||||||
|
send_fun = SendFun } = PState) ->
|
||||||
amqp_channel:notify_received(DeliveryCtx),
|
amqp_channel:notify_received(DeliveryCtx),
|
||||||
case {delivery_dup(Delivery), delivery_qos(ConsumerTag, Headers, PState)} of
|
case {delivery_dup(Delivery), delivery_qos(ConsumerTag, Headers, PState)} of
|
||||||
{true, {?QOS_0, ?QOS_1}} ->
|
{true, {?QOS_0, ?QOS_1}} ->
|
||||||
|
|
@ -292,7 +301,7 @@ amqp_callback({#'basic.deliver'{ consumer_tag = ConsumerTag,
|
||||||
{true, {?QOS_0, ?QOS_0}} ->
|
{true, {?QOS_0, ?QOS_0}} ->
|
||||||
{ok, PState};
|
{ok, PState};
|
||||||
{Dup, {DeliveryQos, _SubQos} = Qos} ->
|
{Dup, {DeliveryQos, _SubQos} = Qos} ->
|
||||||
send_client(
|
SendFun(
|
||||||
#mqtt_frame{ fixed = #mqtt_frame_fixed{
|
#mqtt_frame{ fixed = #mqtt_frame_fixed{
|
||||||
type = ?PUBLISH,
|
type = ?PUBLISH,
|
||||||
qos = DeliveryQos,
|
qos = DeliveryQos,
|
||||||
|
|
@ -324,11 +333,12 @@ amqp_callback({#'basic.deliver'{ consumer_tag = ConsumerTag,
|
||||||
end;
|
end;
|
||||||
|
|
||||||
amqp_callback(#'basic.ack'{ multiple = true, delivery_tag = Tag } = Ack,
|
amqp_callback(#'basic.ack'{ multiple = true, delivery_tag = Tag } = Ack,
|
||||||
PState = #proc_state{ unacked_pubs = UnackedPubs }) ->
|
PState = #proc_state{ unacked_pubs = UnackedPubs,
|
||||||
|
send_fun = SendFun }) ->
|
||||||
case gb_trees:size(UnackedPubs) > 0 andalso
|
case gb_trees:size(UnackedPubs) > 0 andalso
|
||||||
gb_trees:take_smallest(UnackedPubs) of
|
gb_trees:take_smallest(UnackedPubs) of
|
||||||
{TagSmall, MsgId, UnackedPubs1} when TagSmall =< Tag ->
|
{TagSmall, MsgId, UnackedPubs1} when TagSmall =< Tag ->
|
||||||
send_client(
|
SendFun(
|
||||||
#mqtt_frame{ fixed = #mqtt_frame_fixed{ type = ?PUBACK },
|
#mqtt_frame{ fixed = #mqtt_frame_fixed{ type = ?PUBACK },
|
||||||
variable = #mqtt_frame_publish{ message_id = MsgId }},
|
variable = #mqtt_frame_publish{ message_id = MsgId }},
|
||||||
PState),
|
PState),
|
||||||
|
|
@ -338,8 +348,9 @@ amqp_callback(#'basic.ack'{ multiple = true, delivery_tag = Tag } = Ack,
|
||||||
end;
|
end;
|
||||||
|
|
||||||
amqp_callback(#'basic.ack'{ multiple = false, delivery_tag = Tag },
|
amqp_callback(#'basic.ack'{ multiple = false, delivery_tag = Tag },
|
||||||
PState = #proc_state{ unacked_pubs = UnackedPubs }) ->
|
PState = #proc_state{ unacked_pubs = UnackedPubs,
|
||||||
send_client(
|
send_fun = SendFun }) ->
|
||||||
|
SendFun(
|
||||||
#mqtt_frame{ fixed = #mqtt_frame_fixed{ type = ?PUBACK },
|
#mqtt_frame{ fixed = #mqtt_frame_fixed{ type = ?PUBACK },
|
||||||
variable = #mqtt_frame_publish{
|
variable = #mqtt_frame_publish{
|
||||||
message_id = gb_trees:get(
|
message_id = gb_trees:get(
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@
|
||||||
|
|
||||||
-export([conserve_resources/3, start_keepalive/2]).
|
-export([conserve_resources/3, start_keepalive/2]).
|
||||||
|
|
||||||
|
-export([ssl_login_name/1]).
|
||||||
|
|
||||||
-include_lib("amqp_client/include/amqp_client.hrl").
|
-include_lib("amqp_client/include/amqp_client.hrl").
|
||||||
-include("rabbit_mqtt.hrl").
|
-include("rabbit_mqtt.hrl").
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue