2016-05-23 8 views
0

Wir haben ein kleines Code-Snippet, um Nachrichten von einer SQLite-Datenbank zu übertragen (als eine gemeinsame Objektdatei importieren). zMQ wird verwendet, um einige Daten wie Zeilen-ID, Tabellenname usw. zu übertragen, aber es gibt ein Problem mit der Kommunikation, wenn ein "Schlaf" aus dem Code entfernt wird.ZMQ, PUB/SUB, verlorene Nachrichten, wenn "sleep" entfernt wird

Das Code-Snippet verfügt über eine Struktur, die zum sqlite-Datenbankclient passt.

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); 
} 

Wenn ich den Schlafanruf habe funktioniert alles gut, aber ohne nichts gesendet wird. Also habe ich versucht den LINGER-Befehl zu benutzen. Aber es scheint das Verhalten nicht zu ändern. Versucht, den LINGER-Parameter sowohl vor als auch nach dem Verbindungsaufbau ohne Erfolg einzustellen.

Der Zweck des Codes besteht darin, die Nachricht so schnell wie möglich auszuführen und zu senden und zum Datenbank-Client zurückzukehren. Wir haben nicht die Zeit in diesem Rückruf zu schlafen.

+0

Ist der Schlaf(), oder was auch immer, wirklich wichtig, wenn Sie das totale Gewicht eines Verbindungs-/Verbindungs-Protokolls tragen? Ihre Leistung wird sowieso hoffnungslos schlecht sein. –

+0

Könnte so sein, aber das ist, was ich derzeit habe und ich kann nichts in diesem Moment ändern. Mit dem PAIR-Protokoll hatten wir eine gute Leistung für das embedded Gerät, aber ich muss es wegen mehrerer Publisher an pub/sub anpassen. – Easyrider

+0

haben Sie versucht, Rückgabewerte von zmq-Funktionsaufrufen zu protokollieren? – user3188346

Antwort

0

Der Anruf an zmq_send ist asyncronous, es sendet die Nachricht tatsächlich nicht. Es wird in Puffer innerhalb des Sockets/Kontexts kopiert und später gesendet. Wenn Sie den Kontext/Socket direkt nach dem Aufruf von send zerstören, wird es wahrscheinlich die Nachricht vor dem Senden töten.

Wenn dies schnell sein soll, dann wollen Sie nicht jedes Mal einen Kontext und einen Socket erstellen. Wenn Sie einen Zeromq-Kontext erstellen, wird mindestens ein Thread erstellt.

Sie möchten wahrscheinlich einen Kontext und Socket an anderer Stelle erstellen und nur senden innerhalb des Rückrufs aufrufen. Der Socket-Pointer könnte in die Userdata gehen?

+0

Ja, es wäre natürlich besser, den Kontext und Socket woanders zu erstellen, aber ich weiß nicht, wie es bei Erweiterungen für SQLite zu tun ist. Momentan arbeite ich an einer mqtt Lösung. Einige Tests zeigen, dass (in Python) ein connect, send und destroy in ca. 15ms erledigt werden kann. Was ist gut genug für dieses Gerät. Mit zmq habe ich die gleichen Nummern, ohne dass tatsächlich Daten gesendet werden. :( – Easyrider

+0

Wenn Sie den Callback registrieren, dann können Sie an dieser Stelle einen Socket als Benutzerdaten übergeben? – David

+0

Es tut mir leid, aber es war eine lange Zeit her ich baute C-Programme, und Erweiterungen zu SQLite ist nicht in meiner Gegend, also weiß ich nicht, wie man einen Socket in den Extensions übergibt – Easyrider