2016-05-23 6 views
0

SQLiteデータベースからメッセージをプッシュする小さなコードスニペットがあります(共有オブジェクトファイルとしてインポート)。 zMQは行ID、テーブル名などのデータをプッシュするために使用されますが、コードから「スリープ」が削除されたときに通信に問題があります。"sleep"が削除されたときにZMQ、PUB/SUBのメッセージが失われる

コードスニペットは、sqliteデータベースクライアントに適合する構造を持っています。

void callback (void *user_data,int op,char const *dbn,char const *tn, sqlite3_int64 row_id) 
{ 
    char* optext = ""; 
    char zmq_string[80]; 
    int string_length; 
    char* connection; 
    int linger = 1000; 

    void *context = zmq_ctx_new(); 
    void *sender = zmq_socket (context, ZMQ_PUB); 

    connection = "tcp://localhost:" "7676"; 
    zmq_setsockopt(sender, ZMQ_LINGER, &linger, sizeof (linger)); 
    zmq_connect (sender, connection); 
    string_length = sprintf(zmq_string, "{\"row\":\"%lld\",\"table\":\"%s\"}", (long long)row_id, tn); 
    //sleep(1); 

    zmq_send (sender, zmq_string, string_length, 0); 
    //sleep(1); 
    zmq_close (sender); 
    zmq_ctx_destroy (context); 
} 

スリープコールがあると、すべて正常に動作しますが、何もせずに送信されます。 LINGERコマンドを使用しようとしました。しかし、それは行動を変えないようです。成功することなくconnectの呼び出しの前後にLINGERパラメータを設定しようとしました。

コードの目的は、できるだけ早くメッセージを実行して送信し、データベースクライアントに返すことです。このコールバックでは眠る時間がありません。

+0

sleep()などは、接続/切断プロトコルの重量を乗り越えているときには本当に重要ですか?とにかくあなたのパフォーマンスは絶望的に悪くなるでしょう。 –

+0

そうかもしれないが、これは私が現在持っているものであり、私はこの時点で何も変更できない。私たちは組み込みデバイスのために十分な性能を持っていましたが、複数のパブリッシャのためにpub/subに接続する必要があります。 – Easyrider

+0

zmq関数呼び出しからの戻り値をログに記録しようとしましたか? – user3188346

答えて

0

zmq_sendの呼び出しは非同期です。実際にはメッセージを送信しません。ソケット/コンテキスト内のバッファにコピーされ、後で送信されます。あなたがsendを呼び出した直後にコンテキスト/ソケットを破壊すると、送信前にメッセージが殺される可能性があります。

これが速ければ、毎回コンテキストとソケットを作成する必要はありません。 zeromqコンテキストを作成すると、少なくとも1つのスレッドが作成されます。

コンテキストとソケットを別の場所に作成し、コールバック内でsendを呼び出すだけです。ソケットポインタはユーザデータに入りますか?

+0

もちろん、コンテキストとソケットを別の場所に作成する方が良いでしょうが、sqliteの拡張機能についてはわかりません。現在私は代わりにmqttソリューションを開発中です。いくつかのテストでは、(Pythonで)1つの接続、送信、および破棄が約15msで実行できることが示されています。このデバイスには十分なものです。 zmqでは、実際に送信されたデータはなく、同じ番号が付けられています。 : – Easyrider

+0

あなたのコールバックを登録すると、その時点でソケットにユーザデータとして渡すことができますか? – David

+0

申し訳ありませんが、それはずっと前です。私はCプログラムを構築しました。 – Easyrider

関連する問題