Several fixes to make RabbitMQ a player.

* extlib/Stomp.php
    -spaces for tabs (we're on PEAR, right?)
    - send: initialize the $properties parameter as array() instead of null
      this prevents unsetting $headers if $properties was not set
      (besides that, it's the proper way to initialize an array)
    - subscribe: insert FIXME's on ActiveMQ specifics
    - ack: make sure the content-length header is set *and* is zero.
      I have seen the header set to '3' there but could not find where it
      came from, this is at least safe.
    - disconnect: typo in $headers variable
    - readFrame: use fgets() instead of gets() so that RabbitQ, which is more protocol strict can also play
  * extlib/Stomp/Frame.php
    - spaces for tabs
    - add note on possibly protocol violating linefeed
  * extlib/Stomp/Message.php
    - space for tabs
    - add content-length header for message
  * lib/stompqueuemanager.php
    - use the notice for logging, not the frame
This commit is contained in:
Marcel van der Boom 2009-09-08 22:21:33 +02:00 committed by Craig Andrews
parent a73162d3eb
commit c04987018c
4 changed files with 123 additions and 99 deletions

View File

@ -237,7 +237,7 @@ class Stomp
* @param boolean $sync Perform request synchronously
* @return boolean
*/
public function send ($destination, $msg, $properties = null, $sync = null)
public function send ($destination, $msg, $properties = array(), $sync = null)
{
if ($msg instanceof Stomp_Frame) {
$msg->headers['destination'] = $destination;
@ -319,8 +319,10 @@ class Stomp
public function subscribe ($destination, $properties = null, $sync = null)
{
$headers = array('ack' => 'client');
// FIXME: this seems to be activemq specific, but not hurting rabbitmq?
$headers['activemq.prefetchSize'] = $this->prefetchSize;
if ($this->clientId != null) {
// FIXME: this seems to be activemq specific, but not hurting rabbitmq?
$headers["activemq.subcriptionName"] = $this->clientId;
}
if (isset($properties)) {
@ -433,21 +435,27 @@ class Stomp
*/
public function ack ($message, $transactionId = null)
{
if ($message instanceof Stomp_Frame) {
$frame = new Stomp_Frame('ACK', $message->headers);
$this->_writeFrame($frame);
return true;
} else {
// Handle the headers,
$headers = array();
if ($message instanceof Stomp_Frame) {
// Copy headers from the object
// FIXME: at least content-length can be wrong here (set to 3 sometimes).
$headers = $message->headers;
} else {
if (isset($transactionId)) {
$headers['transaction'] = $transactionId;
}
$headers['message-id'] = $message;
}
// An ACK has no content
$headers['content-length'] = 0;
// Create it and write it out
$frame = new Stomp_Frame('ACK', $headers);
$this->_writeFrame($frame);
return true;
}
}
/**
* Graceful disconnect from the server
*
@ -517,15 +525,25 @@ class Stomp
$rb = 1024;
$data = '';
do {
$read = fgets($this->_socket, $rb);
$read = fread($this->_socket, $rb);
if ($read === false) {
$this->_reconnect();
return $this->readFrame();
}
$data .= $read;
$len = strlen($data);
} while (($len < 2 || ! ($data[$len - 2] == "\x00" && $data[$len - 1] == "\n")));
$continue = true;
// ActiveMq apparently add \n after 0 char
if($data[$len - 2] == "\x00" && $data[$len - 1] == "\n") {
$continue = false;
}
// RabbitMq does not
if($data[$len - 1] == "\x00") {
$continue = false;
}
} while ( $continue );
list ($header, $body) = explode("\n\n", $data, 2);
$header = explode("\n", $header);
$headers = array();

View File

@ -74,7 +74,8 @@ class Stomp_Frame
$data .= "\n";
$data .= $this->body;
return $data .= "\x00\n";
$data .= "\x00\n"; // Should there really be a linefeed here?
return $data;
}
}
?>

View File

@ -29,8 +29,12 @@ require_once 'Stomp/Frame.php';
*/
class Stomp_Message extends Stomp_Frame
{
public function __construct ($body, $headers = null)
public function __construct ($body, $headers = array())
{
if(!isset($headers['content-length'])) {
// TODO: log this, to see if this is correct
$headers['content-length'] = strlen($body);
}
$this->_init("SEND", $headers, $body);
}
}

View File

@ -141,10 +141,11 @@ class StompQueueManager
$this->con->ack($frame);
} else {
if ($handler->handle_notice($notice)) {
$this->_log(LOG_INFO, 'Successfully handled notice '. $notice->id .' posted at ' . $frame->headers['created'] . ' in queue '. $queue);
$this->_log(LOG_INFO, 'Successfully handled notice '. $notice->id .' originally posted at ' . $notice->created . ' in queue '. $queue);
$this->con->ack($frame);
} else {
$this->_log(LOG_WARNING, 'Failed handling notice '. $notice->id .' posted at ' . $frame->headers['created'] . ' in queue '. $queue);
$this->_log(LOG_WARNING, 'Failed handling notice '. $notice->id .' originally posted at ' . $notice->created . ' in queue '. $queue);
// FIXME we probably shouldn't have to do
// this kind of queue management ourselves
$this->con->ack($frame);