gpt4 book ai didi

php - React ZMQ,路由器到经销商,不工作。 ZMQ 4.0.5

转载 作者:搜寻专家 更新时间:2023-10-31 21:07:14 30 4
gpt4 key购买 nike

我想用 React 做一个异步路由器到经销商消息传递,但它不工作。 http://zguide.zeromq.org/php:rtdealer中的代码正在工作,但我无法确定我在做什么不同。我正在使用 libzmq 4.0.5

这是我的代码:

$context = new React\ZMQ\Context($loop);

$worker = $context->getSocket(\ZMQ::SOCKET_DEALER);
$worker->setSockOpt(\ZMQ::SOCKOPT_IDENTITY, 'A');
$worker->connect('tcp://127.0.0.1:5556');
$worker->send('END');

$worker->on('error', function ($e) {
var_dump($e->getMessage());
});

$worker->on('messages', function($msg) use ($worker) {
echo 'Dealer messages'. PHP_EOL;
var_dump($msg);
});

$worker->on('message', function($msg) use ($worker) {
echo 'Dealer message'. PHP_EOL;
var_dump($msg);
});

$router = $context->getSocket(\ZMQ::SOCKET_ROUTER);
$router->bind('tcp://127.0.0.1:5556');

$i = 0;
$loop->addPeriodicTimer(1, function (React\EventLoop\Timer\Timer $timer) use (&$i, $router) {
echo 'Time to send!'. PHP_EOL;
$i++;
$router->send('A', \ZMQ::MODE_SNDMORE);
$router->send('END');
});

$router->on('messages', function($msg) use ($router) {
echo 'Router messages'. PHP_EOL;
var_dump($msg);
});

$router->on('message', function($msg) {
echo 'Router message'. PHP_EOL;
var_dump($msg);
});

$loop->run();

问题是只有经销商发送第一条消息“END”。之后,路由器尝试发送消息,但经销商没有收到消息。

另外,这个函数好像只调用了一次:

// \React\ZMQ\SocketWrapper
public function handleReadEvent()
{
$messages = $this->socket->recvmulti(ZMQ::MODE_NOBLOCK);
echo 'Receiving...'; // Added
var_dump($messages); // Added

if ($messages !== false) {
if (count($messages) === 1) {
$this->emit('message', array($messages[0]));
}

$this->emit('messages', array($messages));
}
}

输出是:

Receiving...array(2) {
[0]=>
string(1) "A"
[1]=>
string(3) "END"
}
Router messages
array(2) {
[0]=>
string(1) "A"
[1]=>
string(3) "END"
}
Time to send!
Time to send!
Time to send!
Time to send!
Time to send!
...

编辑:

修改了dealer连接之前绑定(bind)路由器的代码,问题依旧:

$loop = React\EventLoop\Factory::create();

$context = new React\ZMQ\Context($loop);

$router = $context->getSocket(\ZMQ::SOCKET_ROUTER);
$router->bind('tcp://127.0.0.1:5556');

$loop->addPeriodicTimer(10, function (React\EventLoop\Timer\Timer $timer) use ($router) {
echo 'Router sending messages with an interval of 10 seconds'. PHP_EOL;
$router->send('A', \ZMQ::MODE_SNDMORE);
$router->send('END');
});

$router->on('messages', function($msg) use ($router) {
echo 'Router messages'. PHP_EOL;
var_dump($msg);
});

$router->on('message', function($msg) {
echo 'Router message'. PHP_EOL;
var_dump($msg);
});

$worker = $context->getSocket(\ZMQ::SOCKET_DEALER);

$loop->addPeriodicTimer(5, function (React\EventLoop\Timer\Timer $timer) use ($worker) {
echo 'After 5 seconds from router binding, connect the dealer and send something'. PHP_EOL;
$worker->setSockOpt(\ZMQ::SOCKOPT_IDENTITY, 'A');
$worker->connect('tcp://127.0.0.1:5556');
$worker->send('END');
$timer->getLoop()->cancelTimer($timer); // Cancel the timer after connecting
});

$worker->on('error', function ($e) {
var_dump($e->getMessage());
});

$worker->on('messages', function($msg) use ($worker) {
echo 'Dealer messages'. PHP_EOL;
var_dump($msg);
});

$worker->on('message', function($msg) use ($worker) {
echo 'Dealer message'. PHP_EOL;
var_dump($msg);
});

$loop->run();

这是终端输出:

After 5 seconds from router binding, connect the dealer and send something
Receiving...array(2) {
[0]=>
string(1) "A"
[1]=>
string(3) "END"
}
Router messages
array(2) {
[0]=>
string(1) "A"
[1]=>
string(3) "END"
}
Router sending messages with an interval of 10 seconds
Router sending messages with an interval of 10 seconds
Router sending messages with an interval of 10 seconds
Router sending messages with an interval of 10 seconds
Router sending messages with an interval of 10 seconds
Router sending messages with an interval of 10 seconds
Router sending messages with an interval of 10 seconds
Router sending messages with an interval of 10 seconds

最佳答案

我终于解决了这个问题。在@Jason 的评论 Not having used PHP/React, are you certain your namespacing is correct? 的帮助下,我查看了调用的 send 方法。这个方法看起来像这样:

// \React\ZMQ\SocketWrapper

public function send($message)
{
echo 'Inside send, sending message'. PHP_EOL; //This line was added by myself
$this->buffer->send($message);
}

然后,我想:好吧,如果我这样调用这个方法:

$router->send('A', \ZMQ::MODE_SNDMORE);

第二个参数永远不会被传递。

然后,我看到sendmulti方法没有在SocketWrapper中实现,__call方法在这个SocketWrapper中实现 类直接调用 ZMQ api for PHP 中实现的方法,因此我尝试调用 sendmulti 将这两个参数包装在一个数组中。它起作用了,所以我尝试调用第一个传递相同数组的 send 方法,我不知道为什么但它也起作用了,所以诀窍是调用:

$router->send(array('A', \ZMQ::MODE_SNDMORE));
$router->send(array('END'));

代替:

$router->send('A', \ZMQ::MODE_SNDMORE);
$router->send('END');

此外,请注意位于 GitHub 存储库中的 ZMQ PHP API,它是错误的。 PhpStorm 以某种方式下载了位于某处的另一个 ZMQ PHP API,该 API 似乎是正确的,sendmulti方法原型(prototype)在此 API 中如下所示:

public function sendmulti(array $message, $mode = 0)

令人惊讶的是,以下对该方法的调用似乎给出了相同的结果:

$router->send(array('A', \ZMQ::MODE_SNDMORE));
$router->send(array('A'), \ZMQ::MODE_SNDMORE);

关于php - React ZMQ,路由器到经销商,不工作。 ZMQ 4.0.5,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30469459/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com