Потерянные сообщения ZeroMQ с подписчиком PHP - PullRequest
1 голос
/ 13 января 2012

Я использую zeromq с привязками php для подключения к модулю zmq в Freeswitch (программный коммутатор VOIP).

Коротко: я проигрываю События. Долго: Модуль zmq во Freeswitch реализован на c ++ как издатель. Мой PHP-код выглядит следующим образом:

<?php
  $context = new ZMQContext();

  echo "connect to freeswitch zmq module...";
  $sub = new ZMQSocket($context, ZMQ::SOCKET_SUB);
  $sub->setSockOpt(ZMQ::SOCKOPT_SUBSCRIBE,"");
  $sub->connect("tcp://192.168.20.73:5556");
  $hwm = $sub->getSockOpt(ZMQ::SOCKOPT_HWM);
  echo "ok.hwm: $hwm\n";

  echo "looping\n";
  while(1) {
  $data = $sub->recv();
  $d = json_decode($sub->recv(),TRUE);
  $event = $d["Event-Name"];
  $date = $d["Event-Date-Local"];
  $ts = $d["Event-Date-Timestamp"];
  $msgnr = $d["ZMQ-Msg-Cnt"];
  echo "PHP: $date msg# $msgnr $ts received $event\n";
}
?>

ZMQ-Msg-Cnt - это порядковый номер, который я встроил в модуль zmq в freeswitch. Я вижу, что каждое второе сообщение потеряно. tcpdump показывает, что сообщение получено zmq.

Я преобразовал код PHP в C и теперь я могу получать каждое сообщение. C:

#include "zhelpers.h"
#include "cJSON.h"

int main (void)
{
    void *context = zmq_init (1);

    void *subscriber = zmq_socket (context, ZMQ_SUB);
    zmq_connect (subscriber, "tcp://192.168.20.73:5556");
    zmq_setsockopt (subscriber, ZMQ_SUBSCRIBE, "", 0);

    while (1) {
        char *string = s_recv (subscriber);

        cJSON *root = cJSON_Parse(string);
        int msgcnt = cJSON_GetObjectItem(root,"ZMQ-Msg-Cnt")->valueint;

        printf("C: %s msg# %s %s received %s\n",
            cJSON_GetObjectItem(root,"Event-Date-Local")->valuestring,
            cJSON_GetObjectItem(root,"ZMQ-Msg-Cnt")->valuestring,
            cJSON_GetObjectItem(root,"Event-Date-Timestamp")->valuestring,
            cJSON_GetObjectItem(root,"Event-Name")->valuestring
        );
        cJSON_Delete(root);
        free (string);
    }

zmq_close (subscriber);
zmq_term (context);
return 0;
}

Что-то не так с PHP-кодом? Есть ли какие-нибудь хитрости / обязательные для исполнения советы для PHP?

Заранее спасибо, Джеральд Вебер

1 Ответ

1 голос
/ 13 января 2012

Вы вызываете функцию recv дважды, поэтому она загружает одно сообщение, пропускает любую обработку, а затем загружает второе:

$data = $sub->recv();
// This is your first message, called in a blocking mode

$d = json_decode($sub->recv(),TRUE);
// and here's your second one, called in a non-blocking mode

Измените эти две строки на одну:

$d = json_decode($sub->recv());
...