2014-06-09 53 views
0

目前,我正在嘗試使用ZMQ發送/接收郵件的簡單代碼。代碼如下未通過ZMQ發送的郵件

/* Create new queue object, there needs to be a server at the other end */ 
    $queue = new ZMQSocket(new ZMQContext(), ZMQ::SOCKET_REQ); 
    $queue->connect("tcp://127.0.0.1:5555"); 

/* Assign socket 1 to the queue, send and receive */ 
    $retries = 5; 
    $sending = true; 

/* Start a loop */ 
    do { 
    try { 
    /* Try to send/receive */ 
    if ($sending) { 
     echo "Sending message\n"; 
     $queue->send("This is a message", ZMQ::MODE_NOBLOCK); 
     $sending = false; 
    } else { 
     echo "Got response: " . $queue->recv(ZMQ::MODE_NOBLOCK) . "\n"; 
     echo 'Complete'; 
     break; 
    } 
    } catch (ZMQSocketException $e) { 
    /* EAGAIN means that the operation would have blocked, retry */ 
    if ($e->getCode() === ZMQ::ERR_EAGAIN) { 
     echo " - Got EAGAIN, retrying ($retries)\n"; 
    } else { 
     die(" - Error: " . $e->getMessage()); 
    } 
    } 
    /* Sleep a bit between operations */ 
    usleep(5); 
    } while (--$retries); 

,當我在控制檯運行此腳本,我的輸出是

Sending message 
Got response: 
Complete 

我相信,雖然沒有引發的錯誤,但是我的消息不實際發送。我也運行netstat命令,但我沒有發現任何進程監聽端口5555.理想情況下,應該有一個(當前)。但建立連接時不會出現異常情況。 有什麼我失蹤?

回答

0

當你說沒有進程正在偵聽端口5555時,這可能意味着你的服務器沒有啓動並運行。即使沒有服務器,您的客戶端也不會拋出任何錯誤,它只是設置並等待服務器聯機(至少在此處使用您的特定設置)。

在這種情況下,由於您使用的是非阻塞模式,因此它會在第一遍循環中發送消息(爲什麼在循環中發送消息?),但它贏得了'實際上發送任何東西,因爲服務器不在那裏。然後它會試圖通過循環的第二遍接收,但是由於套接字沒有準備好接收,它看起來會失敗,而不會引發異常。由於不會引發異常,它會到達您的break語句,退出循環,然後就完成了。

首先,你的send調用應該發生在循環之前,它只是你想要做的一次。

然後,當您recv時,將結果存儲在變量中並測試空。留下try/catch代碼。結果應該是這樣的:

/* Create new queue object, there needs to be a server at the other end */ 
$queue = new ZMQSocket(new ZMQContext(), ZMQ::SOCKET_REQ); 
$queue->connect("tcp://127.0.0.1:5555"); 

/* Assign socket 1 to the queue, send and receive */ 
$retries = 5; 
echo "Sending message\n"; 
$queue->send("This is a message", ZMQ::MODE_NOBLOCK); 

/* Start a loop */ 
do { 
    try { 
     /* Try to receive */ 
     $response = $queue->recv(ZMQ::MODE_NOBLOCK); 
     if (!empty($response)) { 
      echo "Got response: " . $response . "\n"; 
      echo 'Complete'; 
      break; 
     } 
     else { 
      echo "we probably haven't even sent the original request yet, retrying ($retries)\n"; 
     } 
    } 
    catch (ZMQSocketException $e) { 
     /* EAGAIN means that the operation would have blocked, retry */ 
     if ($e->getCode() === ZMQ::ERR_EAGAIN) { 
      echo " - Got EAGAIN, retrying ($retries)\n"; 
     } else { 
      die(" - Error: " . $e->getMessage()); 
     } 
    } 
    /* Sleep a bit between operations */ 
    usleep(5); 
} while (--$retries); 

echo "END OF LINE"; 

...記住這是一個小的修復到客戶端的代碼,使得它表現多一點理性,我還是相信你的實際問題是,服務器ISN不會跑。

+0

謝謝。我會檢查這一點。實際上這個代碼是從php.net文檔站點 –

+0

挑選的。我也沒有找到任何指南,說我們需要像rabbitmq一樣啓動zmq服務器。您可以請我指點指南,說明如何啓動zmq服務器? –

+0

所以......你是說這是你運行的唯一腳本?當我說「服務器」時,我的意思是「你想發送消息到另一個腳本,並且會迴應」。如果您沒有運行ZMQ的任何其他進程發送到,那麼您當然不會發送或獲取響應。 – Jason

0

請添加服務器代碼。您正在顯示客戶端代碼。由於問題似乎出現在服務器中,並且您還聲明服務器在netstat中不可見,所以問題很可能在那裏。