简体   繁体   English

Activemq和Php Stomp:同步生产者样本

[英]Activemq and Php Stomp: synchronous producer sample

I'm trying have this principle working: 我正在尝试使这个原理起作用:

  • a producer that sends one message (1) and waits for ack which contains some result (json result of an operation, actually) 发送一条消息(1)并等待包含某些结果的ack的生产者(实际上是操作的json结果)
  • a consumer that checks all pending messages every 5 seconds , and handle all of them in one row, and acknowlegdes all of them in one row, then wait again 5 seconds (infinite loop). 使用者每隔5秒检查一次所有待处理的消息,并在一行中处理所有消息,并在一行中确认所有消息,然后再次等待5秒(无限循环)。

Here are the 30 lines of my stompproducer.php : 这是我的stompproducer.php的30行:

<?php

function msg($txt)
{
    echo date('H:i:s > ').$txt."\n";
}

$queue  = '/aaaa';
$msg    = 'bar';
if (count($argv)<3) {
    echo $argv[0]." [msg] [nb to send]\n";
    exit(1);
}
$msg     = (string)$argv[1];
$to_send = intval($argv[2]);

try {
    $stomp = new Stomp('tcp://localhost:61613');
    while (--$to_send) {
        msg("Sending...");
        $result = $stomp->send(
            $queue,
            $msg." ". date("Y-m-d H:i:s"),
            array('receipt' => 'message-123')
        );
        echo 'result='.var_export($result,true)."\n";
        msg("Done.");
    }
} catch(StompException $e) {
    die('Connection failed: ' . $e->getMessage());
}

Here are the 30 lines of my stompconsumer.php : 这是我的stompconsumer.php的30行:

<?php

$queue  = '/aaaa';
$_waitTimer=5000000;
$_timeLastAsk = microtime(true);

function msg($txt)
{
    echo date('H:i:s > ').$txt."\n";
}

try {
    $stomp = new Stomp('tcp://localhost:61613');
    $stomp->subscribe($queue, array('activemq.prefetchSize' => 40));
    $stomp->setReadTimeout(0, 10000);
    while (true) {
        $frames_read=array();
        while ($stomp->hasFrame()) {
            $frame = $stomp->readFrame();
            if ($frame != null) {
                array_push($frames_read, $frame);
            }
            if (count($frames_read)==40) {
                break;
            }
        }
        msg("Nombre de frames lues : ".count($frames_read));
        msg("Pause...");
        $e=$_waitTimer-(microtime(true)-$_timeLastAsk);
        if ($e>0) {
            usleep($e);
        }
        if (count($frames_read)>0) {
            msg("Ack now...");
            foreach ($frames_read as $frame) {
                $stomp->ack($frame);
            }
        }
        $_timeLastAsk = microtime(true);
    }
} catch(StompException $e) {
    die('Connection failed: ' . $e->getMessage());
}

I can't manage to do synchronous producer, ie producer that waits for consumer ack. 我无法管理同步生产者,即等待消费者确认的生产者。 If you run the samples I've done here, you'll see that producer instantaneously sends all messages, then quits, with all "true" like "ok" results when calling $stomp->send() . 如果运行我在此处完成的示例,您将看到生成器在发送$stomp->send()立即发送所有消息,然后退出,并显示所有“ true”(如“ ok”)结果。 I still haven't found good examples, neither good documentation with a simple blocking sample. 我仍然没有找到好的示例,也没有找到带有简单阻止示例的好的文档。

What shall I do to make my producer blocking until the consumer sends its ack? 在消费者发送确认之前,我应该怎么做才能阻止生产者?

NB: I've read all documentation here and the stomp php questions on stackoverflow here and here . 注:我读过的所有文件在这里和计算器的蹬PHP的问题, 在这里这里

From the question it sounds like you are looking for a request / response type messaging pattern. 从这个问题看来,您正在寻找一个请求/响应类型的消息传递模式。 This is something you must implement yourself as the STOMP ack you reference is only acking the message to the message broker on behalf of the consumer, the producer has no knowledge of this. 这是您必须实现的事情,因为您引用的STOMP确认仅代表消费者将消息确认给消息代理,生产者对此一无所知。 Request response involves setting a reply-to address on the outbound message and then waiting to receive a response on that address before sending the next message. 请求响应包括在出站消息上设置回复地址,然后在发送下一条消息之前等待在该地址上接收响应。 There are a great many articles out there that document this sort of thing such as this one . 有一个伟大的很多文章,在那里,文件这样的事情,如这一个

Or if you only need to know if the broker has received the message from the client and persisted it then you can use STOMP's built in receipt mechanism to have the broker send you a receipt indicating that it has processed your sent message. 或者,如果您只需要知道经纪人是否已从客户端接收到消息并将其保留,则可以使用STOMP的内置收据机制让经纪人向您发送收据,表明它已处理了已发送的消息。 This however does not guarantee that a consumer has processed the message yet. 但是,这不能保证消费者已经处理了该消息。

First thing to pop t my mind: Take a look at this stomp plugin: 首先想到的是:看一下这个stomp插件:

http://activemq.apache.org/message-redelivery-and-dlq-handling.html http://activemq.apache.org/message-redelivery-and-dlq-handling.html

Another workaround I can thing of is: On producer side: 1. Change your producer to send persistent messages 我可以想到的另一种解决方法是:在生产者端:1.更改生产者以发送持久性消息

On your consumer side: Use a timer. 在您的消费者方面:使用计时器。 1. Read message/frames until empty or max cap reached. 1.阅读消息/帧,直到达到空或最大上限。 2. Create a CURL request and empty packed list of messages 3. Sleep your server for 5 secs 2.创建一个CURL请求并清空邮件的打包列表。3.使服务器休眠5秒钟

You definitely need to test this further, but should work. 您肯定需要进一步测试,但是应该可以。 Once the process wakes up, you should be able to read all messages queued. 进程唤醒后,您应该能够读取所有排队的消息。

Things to consider: - persistent messages will need an expiration time - You'll need ACK on your consumer side to make sure to update status of messages already attended. 需要考虑的事项:-持久性消息将需要一个有效时间-消费者方将需要ACK以确保更新已出席消息的状态。 Use ACK=client so you can ACK all messages acknowledged - It's easier if you don't have to wait for your CURL to respond. 使用ACK = client,以便您可以确认所有已确认的消息-如果您不必等待CURL进行响应,这会更容易。 - Out of the box, it's not supported to send ACK from the consumer (server side). -开箱即用,不支持从使用者(服务器端)发送ACK。

Best of luck 祝你好运

I just remembered, you can try reactphp/stomp library. 我只记得,您可以尝试reactphp / stomp库。 It's an event driven library that might help you. 这是一个事件驱动的库,可能会对您有所帮助。 specially take a look ad the core functionality addPeriodicTimer 特别看一下核心功能addPeriodicTimer

https://github.com/reactphp/stomp https://github.com/reactphp/stomp

Cheers 干杯

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM