我一直在尝试在本地计算机和远程服务器之间使用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;
}
如果我在本地运行代码(一个终端中的“php worker.php”和另一个终端中的“php sender.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
但如果我使用遥控器(mu本地的发送者和遥控器中的接收者),我会得到
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的亚马逊实例(我认为这不会影响,但我会写它以防万一)。
编辑:只是为了澄清,我不想通过互联网发送数据,我只是想在遇到这个问题时以高延迟测试zeromq。
答案 0 :(得分:7)
问题在于Pieter的文档称之为“慢速木匠”。这是错误名称,因为它暗示订阅者/侦听者是问题的根源。事实并非如此。
问题最有可能发生在发行商方面。您是在发布商连接之前发送消息的。
这怎么可能? zmq_connect或zmq_bind返回,因此您必须准备好。 否,你不是。
当connect / bind返回时,显然连接/发布设置未完成。 函数返回后连接完成。
那么你如何解决这个问题呢?简单的方法是等待。这个问题是你不知道等待多长时间,实际时间取决于特定的网络情况和所涉及的硬件。
更好的方法,但更多参与,是为您的发布商地址设置本地订阅者,并重复发布管理消息,一旦收到,就会让您知道自己已经准备就绪。
答案 1 :(得分:4)
解决了这个问题,我在本地和服务器上安装了不同版本的zeromq。如果您收到相同的错误,请检查版本。
注意:Zeromq可以使用互联网。唯一的事情(至少在php中)是你需要确保在关闭进程之前完全发送了消息。在我的测试中,我在不同的计算机之间发送了几次75000随机大小的消息(平均大小:1MB),我得到了所有预期的消息。