Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 如何使用Net::Stomp和带有receive\u框架的事务_Perl_Activemq_Stomp - Fatal编程技术网

Perl 如何使用Net::Stomp和带有receive\u框架的事务

Perl 如何使用Net::Stomp和带有receive\u框架的事务,perl,activemq,stomp,Perl,Activemq,Stomp,我正在使用Net::Stomp修改一些现有代码,从能够处理单个主题改为能够处理多个主题。有人能告诉我这种方法是否可行吗?它现在不起作用了,因为在它需要交易凭证的地方,它会收到关于另一个主题的第一条消息。我想知道我是不是找错人了,然后再去修理它 以下是工作流的外观: # first subscribe to three different queues for $job (qw/ JOB1 JOB2 JOB3 /){ $stomp->subscribe({ "ack" => "c

我正在使用Net::Stomp修改一些现有代码,从能够处理单个主题改为能够处理多个主题。有人能告诉我这种方法是否可行吗?它现在不起作用了,因为在它需要交易凭证的地方,它会收到关于另一个主题的第一条消息。我想知道我是不是找错人了,然后再去修理它

以下是工作流的外观:

# first subscribe to three different queues
for $job (qw/ JOB1 JOB2 JOB3 /){
$stomp->subscribe({
   "ack" => "client",
   "destination" => "/queue/$job"
});

# listen on those three channels...
while($stomp->can_read){

   $frame = $stomp->receive_frame();

   # ... receives a message for JOB1
   # and to start a transaction send a BEGIN frame that looks like this:

    bless({
    command => "BEGIN",
    headers => {
             receipt => "0002",
            transaction => "0001",
       },
    }, "Net::Stomp::Frame")

   # Then looks for a receipt on that frame by calling
   $receipt = $stomp->receive_frame()
不幸的是,当它期待一个接收帧时,它实际上得到了JOB2队列中等待的下一个消息帧

我的问题是,有没有办法让它既能订阅多个主题,又能收到交易收据?还是有更好/更标准的方法来处理

欢迎提供任何提示或建议,谢谢!我也在ActiveMQ列表中交叉发布了这个问题,希望没问题:-/

*更新*

这是一个完整的复制案例:

use Net::Stomp;

use strict;

my $stomp = Net::Stomp->new( { hostname => 'bpdeb', port => '61612' } );
$stomp->connect( { login => 'hello', passcode => 'there' } );

# pre-populate the two queues
$stomp->send( { destination => '/queue/FOO.BAR', body => 'test message' } );
$stomp->send( { destination => '/queue/FOO.BAR2', body => 'test message' } );


# now subscribe to them
$stomp->subscribe({ destination => '/queue/FOO.BAR',
                   'ack'        => 'client',
                   'activemq.prefetchSize' => 1
});
$stomp->subscribe({ destination => '/queue/FOO.BAR2',
                   'ack'        => 'client',
                   'activemq.prefetchSize' => 1
});

# read one frame, then start a transaction asking for a receipt of the 
# BEGIN message
while ($stomp->can_read()){

    my $frame = $stomp->receive_frame; 
    print STDERR "got frame ".$frame->as_string()."\n";


    print STDERR "sending a BEGIN\n";
    my($frame) = Net::Stomp::Frame->new({
        command => 'BEGIN',
            headers => {
            transaction => 123,
            receipt     => 456,
        },
    });

    $stomp->send_frame($frame);

    my $expected_receipt = $stomp->receive_frame;
    print STDERR "expected RECEIPT but got ".$expected_receipt->as_string()."\n";

    exit;
}
此输出(省略细节)

查看网络流量,一旦发送订阅请求,队列中的第一条消息就会通过线路发送到客户端。因此,当我发送BEGIN消息时,来自FOO.BAR2的第一条消息已经在客户端的网络缓冲区中等待,客户端直接从其缓冲区读取FOO.BAR2


所以要么我做错了什么,要么它不能这样工作。

好的,我试过了,效果很好。但你是那个接受帧的人。那么,为什么服务器要向您发送一个收据框架呢

您设置的是代码>“ACK”=“客户端”<代码>,这意味着服务器将把该框架视为“未交付”,直到您另外说。只需将行
$receive=$stomp->receive_frame()
更改为
$stomp->ack({frame=>$frame})

更新 啊,好的,您想通过使用事务来保护
ack
。让我们看一下:有一种方法
send\u transactional
,它可能会执行您想要执行的操作(但它使用
send
帧而不是
ACK


也许您还应该看看,它为模块添加了几个“安全功能”(不幸的是,当我问模块作者时,他没有说任何关于合并该补丁的内容)。

好的,我试过了,效果很好。但你是那个接受帧的人。那么,为什么服务器要向您发送一个收据框架呢

您设置的是代码>“ACK”=“客户端”<代码>,这意味着服务器将把该框架视为“未交付”,直到您另外说。只需将行
$receive=$stomp->receive_frame()
更改为
$stomp->ack({frame=>$frame})

更新 啊,好的,您想通过使用事务来保护
ack
。让我们看一下:有一种方法
send\u transactional
,它可能会执行您想要执行的操作(但它使用
send
帧而不是
ACK


也许您还应该看看,它为模块添加了几个“安全功能”(不幸的是,当我问模块作者时,他没有说要合并该补丁)。

Jan,感谢您查看它,知道它应该可以工作是很有帮助的。因此,我做了更多的研究,并在问题中添加了一个更完整的重新编写案例。感谢您对ACK的评论,我相信原始代码的目的是将ACK放入交易中,因此我希望在发送ACK之前从一开始就获得收据。除非我误解了你的意思……简,谢谢你看了它,知道它应该有用是很有帮助的。因此,我做了更多的研究,并在问题中添加了一个更完整的重新编写案例。感谢您对ACK的评论,我相信原始代码的目的是将ACK放入交易中,因此我希望在发送ACK之前从一开始就获得收据。除非我误解了你的意思。。。
got frame MESSAGE
destination:/queue/FOO.BAR
....

sending a BEGIN

expected RECEIPT but got MESSAGE
destination:/queue/FOO.BAR2
....