【问题标题】:Stuck messages in ZeroMQZeroMQ 中的消息阻塞
【发布时间】:2012-06-23 22:29:32
【问题描述】:

我在使用 ZeroMQ 时遇到了一个奇怪的问题,其中一些消息被卡住了,而当新消息到达时又被解开了。这就像新消息将卡在门上的消息推到了门上(可怕的比较,我知道)。

我的代码很简单:

rep.php

$context = new ZMQContext;
$receiver = new ZMQSocket($context, ZMQ::SOCKET_PULL);
$receiver->connect("tcp://localhost:8022");
$receiver2 = new ZMQSocket($context, ZMQ::SOCKET_PULL);
$receiver2->connect("tcp://localhost:8024");

for (;;) {
    echo $receiver->recv() . PHP_EOL;
    echo $receiver2->recv() . PHP_EOL;
}

cnt.php 和 cnt2.php(相同的代码,不同的端口)

$context = new ZMQContext;
$work = new ZMQSocket($context, ZMQ::SOCKET_PUSH);
$work->bind('tcp://*:8022');
$work->send('Hello World');

cnt.php 发送到 8022,cnt2.php 发送到 8024。它们不时被执行并向 rep.php 发送消息。但是,有些消息会卡住。如果我从 cnt.php 发送 4 条消息,则没有收到任何消息,但是当我从 cnt2.php 发送 1 条消息时,我一次收到 5 条消息。有什么想法吗?

【问题讨论】:

  • 变量名的选择是暗示性的,你真的可以不用它
  • 那真的没关系。 =/

标签: network-programming message-queue zeromq


【解决方案1】:

我不是 PHP 专家,我只是猜测语法和功能。如有错误请指正

echo $receiver->recv() . ' - ' . $receiver2->recv();

recv() 应该是一个阻塞调用。

  1. $receiver->recv() 阻塞,直到收到一些消息。
  2. echo 不会立即回显消息
  3. 您再次被$receiver2->recv() 屏蔽
  4. 只有当你从另一个文件发送消息时才会回显工作,因为它正在等待$receiver2->recv()

由于您想独立处理套接字 recv(),您应该使用轮询或基于事件的异步 I/O。

[尝试的解决方案]

$poll = new ZMQPoll();
$poll->add($receiver, ZMQ::POLL_IN);
$poll->add($receiver2, ZMQ::POLL_IN);
$readable = $writeable = array();
while(true) {
     $events = $poll->poll($readable, $writeable);
     foreach($readable as $socket) {
               $message = $socket->recv();
               echo $message, PHP_EOL;
     }
}

改编自:http://zguide.zeromq.org/php:rrbroker

【讨论】:

  • 如果我先回显 $receiver->recv() 然后回显 $receiver2->recv() 会怎样?
  • rep.php 不是脚本,它一直在运行,等待接收消息。
  • 我改变了行为,消息仍然卡住。检查我的编辑。
  • @vinnylinux:我添加了关于如何更改 red.php 的注释。看到它可能有 PHP 错误,因为我不知道 PHP。我还添加了应该有用的指针
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-17
相关资源
最近更新 更多