Websocket提要更新而不会阻塞主线程

时间:2020-05-08 04:06:33

标签: php websocket

我有一个现有的交易机器人,它可以在循环中同步运行:

  1. 卷曲到订单数据,
  2. 交易-提交/取消报价
  3. 继续

这种方法很好用,但是如果您通过常规HTTPS查询某些订单提要,则它们不是最新的。这些团体提供Websocket提要。 现在这增加了一些复杂性,因为一方面需要处理Websocket消息。另一方面,我正在循环中运行一个机器人。

我已经尝试了事件循环方法。 Fetcher得到了websocket消息的更新,OfferManagerrun方法进行交易:

<?php

$fetcher = new FetchOffersExchangeWebsocket();
$manager = new SellOnlyOfferManager($fetcher);

$loop = \React\EventLoop\Factory::create();
$reactConnector = new \React\Socket\Connector($loop);
$connector = new \Ratchet\Client\Connector($loop, $reactConnector);

$connector('wss://api.trading.net/websocket')
    ->then(function(Ratchet\Client\WebSocket $conn) use($fetcher, $manager) {
        $subscribe = [
            "action" => "subscribe",
            "path" => "orderbook"
        ];

        $conn->send(json_encode($subscribe));

        $conn->on('message', function(\Ratchet\RFC6455\Messaging\MessageInterface $msg) use ($conn, $fetcher, $manager) {
            $message = json_decode((string) $msg, true);

            $fetcher->update($message);
            $manager->run();

        });

    }, function(\Exception $e) use ($loop) {
        echo "Could not connect: {$e->getMessage()}\n";
        $loop->stop();
    });

$loop->run();

出现的第一个明显问题是OfferManager->run()阻止了websocket更新的执行。在这种情况下,如果要执行许多websocket更新,那么我的机器人就落后了,因为它滞留在一些执行run()的较旧消息上,并且都需要时间。

我不确定如何最好地实现它,但是在我看来,我需要在一个线程中更新Websocket,并有办法与bot循环所在的线程共享最终状态(订单簿快照)运行。

有没有通用的方法可以解决这个问题?

是否有租用PHP的干净方法来解决此问题? 看来我可以在前台运行该bot并以某种方式异步运行Websocket更新:https://www.php.net/manual/en/intro.parallel.php,然后使用Channel我可以将该数据传递回前台。

任何提示表示赞赏。

编辑:我不确定如何很好地处理它,但是有用的是使用非阻塞流来获取Websocket数据。 stream_set_blocking($stream, false)。 如果流中没有数据,它将返回空字符串,但不会阻止执行。然后,我可以在流上运行fread直到没有数据,然后可以运行我的$manager->run()。完成后,我将追赶缓冲区中正在等待处理的所有消息。 这不会阻塞执行循环。

0 个答案:

没有答案
相关问题