rabbitmq-erlang-client函数,命令:
amqp_connection:which is used to open connections to a broker and create channels
amqp_channel:which is used to send and receive AMQP commands
基本的客户端操作流程:
1.Establish a connection to a broker:
{ok, Connection} = amqp_connection:start(#amqp_params_network{}),
2.Create a new channel within the open connection:
{ok, Channel} = amqp_connection:open_channel(Connection),
3.Execute AMQP commands with a channel such as sending and receiving messages, creating exchanges and queue or defining routing rules between exchanges and queues:
%% Declare a queue:声明一个queue
#'queue.declare_ok'{queue = Q} = amqp_channel:call(Channel, #'queue.declare'{}),
%% create exchanges and define routing rules
Publish = #'basic.publish'{exchange = <<>>, routing_key = Q},
4.Publish a message:
Payload = <<"foobar">>, %%消息的内容
amqp_channel:cast(Channel, Publish, #amqp_msg{payload = Payload}),
[4.Get message from queue
Get = #'basic.get'{queue = Q},
{#'basic.get_ok'{delivery_tag = Tag}, Content} =amqp_channel:call(Channel, Get),
]
5.close the channel and the connection:
amqp_channel:close(Channel),
amqp_connection:close(Connection),
基本的生产者操作流程:
1.建立一个与borker交互的连接
{ok, Connection} = amqp_connection:start(#amqp_params_network{}),
2.创建一个频道,这个频道是在上面的conn上,用于向borker发送命令的通道
{ok, Channel} = amqp_connection:open_channel(Connection),
3.向borker发送消息,指定要发送到的exchang,及routing_key
Publish = #'basic.publish'{exchange = <<"amq.direct">>, routing_key = <<"my_queue">>, %%该句用于构造命令
amqp_channel:cast(Channel, Publish, #amqp_msg{payload = Payload}, %%发送命令并与定消息内容
4.关闭通信
amqp_channel:close(Channel),
5.关闭连接
amqp_connection:close(Connection),
基本的消费者操作流程:
1.建立一个与borker交互的连接
{ok, Connection} = amqp_connection:start(#amqp_params_network{}),
2.创建一个频道,这个频道是在上面的conn上,用于向borker发送命令的通道
{ok, Channel} = amqp_connection:open_channel(Connection),
3.创建一个队列,该队列是创建在borker的,用它来缓存消息
#'queue.declare_ok'{queue = Q} = amqp_channel:call(Channel, #'queue.declare'{}),
4.将队列与指定的exchang,routing_key进行绑定
Route = #'queue.bind'{queue = Q,exchange = <<"amq.direct">>, routing_key = <<"hello">>},
5.订阅指定队列的消息
Sub = #'basic.consume'{queue = Q, no_ack = ture},
receive
{#'basic.deliver'{}, #amqp_msg{payload = Recv}} %%将收到的消息保存到Recv中
end.
【5.使用轮循的方式去获得消息
Get = #'basic.get'{queue = Q},】
6.消息处理
%% Do something with the message payload
io:format("~p~n", [Recv]),
7.关闭通信
amqp_channel:close(Channel),
8.关闭连接
amqp_connection:close(Connection),
%%生产者命令
#'basic.publish':用于指定向那个exchange,发送及相应的routing_key
Publish = #'basic.publish'{exchange = X, routing_key = Key},
#'P_basic':用于定义消息的属性,如下为定义此消息为persistent messages
Props = #'P_basic'{delivery_mode = 2},
#amqp_msg:构造消息,包括消息属性及消息的内容
Payload = <<"foobar">>,
Msg = #amqp_msg{props = Props, payload = Payload},
向rabbitmq-server发送消息
amqp_channel:cast(Channel, Publish, Msg),
%%消费者命令
#'basic.get':用于指定从哪个队列接收消息,no_ack表示不向server发送ack message
Get = #'basic.get'{queue = Q, no_ack = true},
#'basic.ack':用于创造ack message
#'basic.ack'{delivery_tag = Tag}
#'basic.get_ok':是否成功获得消息
#'basic.get_ok'{delivery_tag = Tag},
#'queue.bind':将消息与exchang等绑定
#'basic.consume':订阅消息
#'basic.deliver':收到消息时的通知命令
#'basic.get_empty':没有消息可读
#'basic.get_empty'{} = amqp_channel:call(Channel, Get),
向rabbitmq-server获得消息
amqp_channel:call(Channel, Get),
向rabbitmq-server确认消息
amqp_channel:cast(Channel, #'basic.ack'{delivery_tag = Tag}),
注:amqp_channel:cast是不要求有返回内容的,而amqp_channel:call是有返回内容
其它:
#'exchange.declare':定义一个新的exchange
#'queue.declare':定义一个新的队列
以及unbind,delete等命令
例子:
------------------------------------------------------------------------------------
%%amqp_send.erl
-module(amqp_send).
-include("amqp_client.hrl").
-compile([export_all]).
test() ->
%% Start a network connection
{ok, Connection} = amqp_connection:start(#amqp_params_network{}),
%% Open a channel on the connection
{ok, Channel} = amqp_connection:open_channel(Connection),
%% Publish a message
Payload = <<"foobar">>,
Publish = #'basic.publish'{exchange = <<"amq.direct">>, routing_key = <<"my_queue">>},
amqp_channel:cast(Channel, Publish, #amqp_msg{payload = Payload}),
%% Close the channel
amqp_channel:close(Channel),
%% Close the connection
amqp_connection:close(Connection),
ok.
---------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
%%amqp_recv.erl
-module(amqp_recv).
-include("amqp_client.hrl").
-compile([export_all]).
test() ->
%% Start a network connection
{ok, Connection} = amqp_connection:start(#amqp_params_network{}),
%% Open a channel on the connection
{ok, Channel} = amqp_connection:open_channel(Connection),
My_queue = #'queue.declare'{queue = <<"my_queue">>},
#'queue.declare_ok'{} = amqp_channel:call(Channel, My_queue),
%% Get the message back from the queue
Get = #'basic.get'{queue = My_queue},
{#'basic.get_ok'{delivery_tag = Tag}, Content}
= amqp_channel:call(Channel, Get),
#amqp_msg{payload = Recv} = Content,
io:format("~p~n", [Recv]),
%% Close the channel
amqp_channel:close(Channel),
%% Close the connection
amqp_connection:close(Connection),
ok.
---------------------------------------------------------------------------------------
%%amqp_recv.erl
%%这里recv使用两种方式,一种是直接get的方式get_test;另一种是通过订阅的方式consume_test.而第一个函数test()是只能获得一个消息的函数
-module(amqp_recv).
-include("amqp_client.hrl").
-compile([export_all]).
test() ->
%% Start a network connection
{ok, Connection} = amqp_connection:start(#amqp_params_network{}),
%% Open a channel on the connection
{ok, Channel} = amqp_connection:open_channel(Connection),
#'queue.declare_ok'{queue = Q} = amqp_channel:call(Channel, #'queue.declare'{}),
Route = #'queue.bind'{queue = Q,
exchange = <<"amq.direct">>,
routing_key = <<"hello">>},
amqp_channel:call(Channel, Route),
timer:sleep(30*1000),
%% Get the message back from the queue
Get = #'basic.get'{queue = Q},
{#'basic.get_ok'{delivery_tag = Tag}, Content} = amqp_channel:call(Channel, Get),
#amqp_msg{payload = Recv} = Content,
io:format("~p~n", [Recv]),
%% Close the channel
amqp_channel:close(Channel),
%% Close the connection
amqp_connection:close(Connection),
ok.
get_test() ->
{ok, Connection} = amqp_connection:start(#amqp_params_network{}),
{ok, Channel} = amqp_connection:open_channel(Connection),
#'queue.declare_ok'{queue = Q} = amqp_channel:call(Channel, #'queue.declare'{}),
Route = #'queue.bind'{queue = Q,
exchange = <<"amq.direct">>,
routing_key = <<"hello">>},
amqp_channel:call(Channel, Route),
loop_get(Channel, Q),
amqp_channel:close(Channel),
amqp_connection:close(Connection),
ok.
loop_get(Channel, Q) ->
Get = #'basic.get'{queue = Q},
case amqp_channel:call(Channel, Get) of
{#'basic.get_ok'{}, #amqp_msg{payload = Recv}} ->
io:format("~p~n", [Recv]),
loop_get(Channel, Q);
_ ->
loop_get(Channel, Q)
end,
ok.
consume_test() ->
{ok, Connection} = amqp_connection:start(#amqp_params_network{}),
{ok, Channel2} = amqp_connection:open_channel(
Connection, {amqp_direct_consumer, [self()]}),
#'queue.declare_ok'{queue = Q} = amqp_channel:call(Channel2, #'queue.declare'{}),
Route = #'queue.bind'{queue = Q,exchange = <<"amq.direct">>,routing_key = <<"hello">>},
amqp_channel:call(Channel2, Route),
amqp_channel:call(Channel2, #'basic.consume'{queue = Q, no_ack = true}),
receive #'basic.consume_ok'{} -> ok end,
consumer_loop(Channel2, 0),
amqp_channel:close(Channel2),
amqp_connection:close(Connection),
ok.
consumer_loop(Channel, NReceived) ->
receive
{#'basic.deliver'{},
#amqp_msg{payload = Recv}} ->
io:format("~p~n", [Recv]),
consumer_loop(Channel, NReceived + 1)
after 30*1000 ->
NReceived
end.
-----------------------------------------------------------------------------
ERL_LIBS=deps erlc -I include/ -o ebin amqp_send.erl
ERL_LIBS=deps erl -pa ebin