1

ZMQ v 3.2.0 のネイティブ C ビルドを実行するデバイスを、pub/sub ZMQ ソケットを使用して JeroMQ (純粋な Java impl) でビルドされた Java アプリケーションと連携させようとしています。ただし、JeroMQ は、メッセージ ペイロードと C 実装の前に異なるフラグ構成を使用しているようです。IIRC、JeroMQ は v 3.2.2 との互換性を意図しているため、これが JeroMQ ポートのバグかどうかはわかりません

私の Java テスト コードは、psenvpub の例に似ています。

public static void main (String[] args) throws Exception {
    // Prepare our context and publisher
    Context context = ZMQ.context(1);
    Socket publisher = context.socket(ZMQ.PUB);

    publisher.bind("tcp://*:15052");
    byte seq = 1;
    while( !Thread.currentThread().isInterrupted() ){
        byte[] message = new byte[8];
        message[0] = 0;
        message[1] = 0;
        message[2] = 0;
        message[3] = 0;
        message[4] = seq++;
        message[5] = 0;
        message[6] = 0;
        message[7] = 0;
        publisher.send(message);
        try{
            Thread.sleep(1000);
        }
        catch(Exception e ){
            break;
        }
    }
}
}

ネイティブ C エンドポイントに perl スクリプトを使用しています。

use strict;
use warnings;

use Vocollect::ZMQ::Context;
use ZMQ::Constants qw(ZMQ_SUB);

my $ctx = Vocollect::ZMQ::Context->new();
my $sock = $ctx->socket(ZMQ_SUB);
$sock->connect('tcp://localhost:15052');
$sock->subscribe('');

while (1) {
    my $msg = $sock->recv(10000);
    print "Received msg\n" if defined($msg);
}

サブスクライバーが最初のメッセージを受信すると、libzmq ソース コードのアサート エラーが原因でクラッシュします。

Assertion failed: options.recv_identity (..\..\..\src\socket_base.cpp:990)

それは次のとおりです。

void zmq::socket_base_t::extract_flags (msg_t *msg_)
{
    //  Test whether IDENTITY flag is valid for this socket type.
    if (unlikely (msg_->flags () & msg_t::identity))
        zmq_assert (options.recv_identity);

    //  Remove MORE flag.
    rcvmore = msg_->flags () & msg_t::more ? true : false;
}

送信されたパケットの Wireshark トレースは、ハンドシェイク シーケンスとフラグが JeroMQ pub/sub とネイティブ C pub/sub で異なることを示しています。JeroMQ またはネイティブ C libzmq の両方を使用するエンドポイントを使用しても、問題は発生しませんでした。

4

0 に答える 0