玩转rabbitmq-delphi(一)

介绍

先决条件

本教程假设 RabbitMQ 已安装并运行在标准端口5672 )上的本地主机上。如果您使用不同的主机、端口或凭据,则需要调整连接设置。

RabbitMQ 是一个消息代理:它接受和转发消息。您可以将其视为邮局:当您将要投递的邮件放入邮箱时,您可以确定信件承运人最终会将邮件递送给您的收件人。在这个比喻中,RabbitMQ 是一个邮箱、一个邮局和一个信件载体。

RabbitMQ 和邮局之间的主要区别在于它不处理纸张,而是接受、存储和转发二进制数据 blob消息

RabbitMQ 和一般的消息传递使用了一些行话。

  • 生产无非就是发送。发送消息的程序是生产者

  • 队列是位于 RabbitMQ 中的邮箱的名称。尽管消息流经 RabbitMQ 和您的应用程序,但它们只能存储在队列中。甲队列仅由主机的存储器&磁盘限制约束,它本质上是一个大的消息缓冲器。许多生产者可以将消息发送到一个队列,许多消费者可以尝试从一个队列接收数据。这是我们表示队列的方式:

  • 消费与接收具有相似的含义。一个消费者是一个程序,主要是等待接收信息:

请注意,生产者、消费者和代理不必驻留在同一主机上;实际上在大多数应用程序中它们没有。应用程序也可以既是生产者又是消费者。

 

在本教程的这一部分,我们将用rabbitmq-delphi编写个小程序;发送单个消息的生产者(发送者),消息传递的是“Hello, World”。

在下图中,“P”是我们的生产者,“C”是我们的消费者。中间的盒子是一个队列——RabbitMQ 代表消费者保留的消息缓冲区。

我们的整体设计如下:

生产者将消息发送到Test.Q队列。

RabbitMQ 库

RabbitMQ 使用多种协议。本教程使用 AMQP 0-9-1,这是一种用于消息传递的开放式通用协议。RabbitMQ 有许多不同语言的客户端。在本教程系列中,我们将使用rabbitmq-delphi 1.0.0,这是 本人翻译自rabbitmq-c的 客户端。 

function main:integer;
var
  port, status : integer;
  ret : Tamqp_rpc_reply;
  socket : Pamqp_socket;
  conn : Pamqp_connection_state;
  props : Tamqp_basic_properties;
  hostname, routingkey, exchange, messagebody: PAnsiChar;
  vl: Tva_list;
begin
  socket := nil;

  hostname := 'localhost';
  port := 5672;
  exchange := 'Test.EX';
  routingkey := 'test-key';
  messagebody := 'Hello, World!';

  if initializeWinsockIfNecessary() < 1 then
 begin
    Writeln('Failed to initialize "winsock": ');
    Exit;
 end;

  conn := amqp_new_connection();
  socket := amqp_tcp_socket_new(conn);
  if  not Assigned(socket) then begin
    Writeln('creating TCP socket failed!');
    Exit;
  end;
  status := amqp_socket_open(socket, hostname, port);
  if status > 0 then begin
    Writeln('opening TCP socket failed!');
    Exit;
  end;
  vl.username := 'sa';
  vl.password := 'admin';
  vl.identity := '';
  die_on_amqp_error(amqp_login(conn, '/', 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, vl),
                     'Logging in');

  amqp_channel_open(conn, 1);
  die_on_amqp_error(amqp_get_rpc_reply(conn), 'Opening channel');

  begin
    props._flags := AMQP_BASIC_CONTENT_TYPE_FLAG or AMQP_BASIC_DELIVERY_MODE_FLAG;
    props.content_type := amqp_cstring_bytes('text/plain');
    props.delivery_mode := 2; { persistent delivery mode }
    amqp_basic_publish(conn, 1, amqp_cstring_bytes(exchange),
                       amqp_cstring_bytes(routingkey), 0, 0,
                       @props, amqp_cstring_bytes(messagebody));
  end;
  die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS),
                    'Closing channel');
  die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS),
                    'Closing connection');
  die_on_error(amqp_destroy_connection(conn), 'Ending connection');
end;


begin
  try
    Main;
  except
    on e:Exception do
      WriteLn(e.Message);
  end;
end.

我们现在连接到本地机器上的代理 - 因此是 localhost。如果我们想连接到另一台机器上的代理,我们只需在此处指定其名称或 IP 地址。

接下来,在发送之前,我们需要确保接收方队列存在。如果我们向不存在的位置发送消息,RabbitMQ 只会丢弃该消息。

此时我们已准备好发送消息。我们的第一条消息将只包含一个字符串Hello, World!我们想将它发送到我们的Test.Q队列。

在 RabbitMQ 中,消息永远不能直接发送到队列,它总是需要经过exchange

 在退出程序之前,我们需要确保网络缓冲区已刷新并且我们的消息实际上已传递到 RabbitMQ。我们可以通过轻轻关闭连接来实现。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值