总是丢失第一条消息


always loses the first message

我一直在尝试用zeromq在本地计算机和远程服务器之间建立一个简单的"管道"。我在本地计算机上测试了这个脚本,它运行得很好,但当我试图使用远程计算机(带有SOCKET_PULL的计算机)作为结束时,我开始出现问题。任何进程发送的第一条消息总是丢失。

代码很简单,

推送(sender.php):

<?php
//Use the specified port or 5555 for sending jobs
$port = $_SERVER['argc'] > 1 ? $_SERVER['argv'][1] : '5555';
$jobN = $_SERVER['argc'] > 2 ? $_SERVER['argv'][2] : '';

$context = new ZMQContext();
//  Socket to send messages on
$sender = new ZMQSocket($context, ZMQ::SOCKET_PUSH);
//If I want to connect to the server I use this line
$sender->connect("tcp://my-server-address.com:$port");
//If I want to connect to localhost I use this line
//$sender->connect("tcp://localhost:$port");
$sender->send('job-1' . ($jobN ? " $jobN" : ''));
$sender->send('job-2' . ($jobN ? " $jobN" : ''));
$sender->send('job-3' . ($jobN ? " $jobN" : ''));
$sender->send('job-4' . ($jobN ? " $jobN" : ''));
$sender->send('job-5' . ($jobN ? " $jobN" : ''));
$sender->send('job-6' . ($jobN ? " $jobN" : ''));
$sender->send('job-7' . ($jobN ? " $jobN" : ''));
$sender->send('job-8' . ($jobN ? " $jobN" : ''));
$sender->send('job-9' . ($jobN ? " $jobN" : ''));
$sender->send('job-10' . ($jobN ? " $jobN" : ''));
echo 'done';

接收器(worker.php)

<?php
//Use the specified port or 5556 for getting finished jobs
$port = $_SERVER['argc'] > 1 ? $_SERVER['argv'][1] : '5555';
//  Prepare our context and socket
$context = new ZMQContext();
$receiver = new ZMQSocket($context, ZMQ::SOCKET_PULL);
$receiver->bind("tcp://*:$port");
$count = 1;
while(true) {
    $string = $receiver->recv();
    echo "Received $string $count'n";
    $count += 1;
}

如果我在本地运行代码(一个终端中为"phpworker.php",另一个终端为"phpsender.php")。

我得到

Received job-1 1
Received job-2 2
Received job-3 3
Received job-4 4
Received job-5 5
Received job-6 6
Received job-7 7
Received job-8 8
Received job-9 9
Received job-10 10

但如果我使用远程(本地的发送器和远程的接收器),我会得到

Received job-2 1
Received job-3 2
Received job-4 3
Received job-5 4
Received job-6 5
Received job-7 6
Received job-8 7
Received job-9 8
Received job-10 9

我做错什么了吗??


注意:我不能锁定发送方(SOCKET_REQ会锁定等待回复的执行)。无论如何,0mq应该在没有锁的情况下工作。注意:我的本地计算机是一台mac计算机,服务器是一个带有ubuntu的amazon实例(我认为这不会影响,但我正在写它,以防万一)。


编辑:只是澄清一下,我不想通过互联网发送数据,我只是想在遇到这个问题时测试具有高延迟的zeromq。

问题是Pieter的文档所称的"慢连接程序"。这是误名,因为它意味着订阅者/侦听器是问题的根源。事实并非如此。

问题很可能出在发行方。您在连接发布者之前发送邮件。

这怎么可能?zmq_connect或zmqbind返回,因此您必须做好准备,你不是。

显然,当连接/绑定返回时,连接/发布设置尚未完成。连接在之后完成,函数返回。

那么你如何解决这个问题呢?简单的方法就是等待。问题是你不知道要等多久,实际时间取决于特定的网络情况和所涉及的硬件。

一个更好但更复杂的方法是为您的发布者地址设置一个本地订阅者,并重复发布一条管理消息,一旦收到该消息,您就会知道自己已经准备好了。

解决了这个问题,我在本地和服务器上安装了不同版本的zeromq。如果出现同样的错误,请检查版本。

注意:Zeromq确实适用于互联网。唯一的一件事(至少在php中)是,您需要确保在关闭流程之前完全发送了消息。在我的测试中,我在不同的计算机之间发送了几次75000条随机大小(平均大小:1MB)的消息,我得到了预期的所有消息。