NAME
Net::STOMP::Client::Frame - Frame support for Net::STOMP::Client
SYNOPSIS
use Net::STOMP::Client::Frame;
# create a connection frame
$frame = Net::STOMP::Client::Frame->new(
command => "CONNECT",
headers => {
login => "guest",
passcode => "guest",
},
);
# get the command
$cmd = $frame->command();
# set the body
$frame->body("...some data...");
# directly get a header field
$msgid = $frame->header("message-id");
DESCRIPTION
This module provides an object oriented interface to manipulate STOMP frames.
A frame object has the following attributes: command
, headers
and body
. The headers
must be a reference to a hash of header key/value pairs. See Net::STOMP::Client::OO for more information on the object oriented interface itself.
METHODS
This module provides the following methods:
- new([OPTIONS])
-
return a new Net::STOMP::Client::Frame object (class method)
- command([STRING])
-
get/set the command attribute
- headers([HASHREF])
-
get/set the headers attribute
- header(NAME)
-
return the value associated with the given name in the header
- body([STRING])
-
get/set the body attribute
- body_reference([STRINGREF])
-
get/set the reference to the body attribute (useful to avoid string copies when manipulating large bodies)
- encode([OPTIONS])
-
encode the given frame and return a binary string suitable to be written to a TCP stream (for instance)
- check()
-
check that the frame is well-formed, see below for more information
FUNCTIONS
This module provides the following functions (which are not exported):
- decode(STRINGREF, [OPTIONS])
-
decode the given string reference and return a complete frame object, if possible, 0 in case there is not enough data for a complete frame or
undef
on error - parse(STRINGREF, [OPTIONS])
-
parse the given string reference and return true on complete frame, 0 on incomplete and
undef
on error; see the "FRAME PARSING" section for more information
FRAME PARSING
The parse() function can be used to parse a frame without decoding it.
It takes as input a string reference (to avoid string copies) and an optional state (a hash reference). It parses the string to find out where the different parts are and it updates its state (if given).
It returns 0 if the string does not hold a complete frame, undef
on error or a hash reference if a complete frame is present. The hash contains the following keys:
- before_len
-
the length of what is found before the frame (only newlines can appear here)
- command_idx, command_len
-
the start position and length of the command
- header_idx, header_len
-
the start position and length of the header
- body_idx, body_len
-
the start position and length of the body
- after_idx, after_len
-
the length of what is found after the frame (only newlines can appear here)
- content_length
-
the value of the "content-length" header (if present)
- total_len
-
the total length of the frame, including before and after parts
Here is how this could be used:
$data = "... read from socket or file ...";
$info = Net::STOMP::Client::Frame::parse(\$data);
if ($info) {
# extract interesting frame parts
$command = substr($data, $info->{command_idx}, $info->{command_len});
# remove the frame from the buffer
substr($data, 0, $info->{total_len}) = "";
}
CONTENT LENGTH
The "content-length" header is special because it is used to indicate the length of the body but also the JMS type of the message in ActiveMQ as per http://activemq.apache.org/stomp.html.
If you do not supply a "content-length" header, following the protocol recommendations, a "content-length" header will be added if the frame has a body.
If you do supply a numerical "content-length" header, it will be used as is. Warning: this may give unexpected results if the supplied value does not match the body length. Use only with caution!
Finally, if you supply an empty string as the "content-length" header, it will not be sent, even if the frame has a body. This can be used to mark a message as being a TextMessage for ActiveMQ. Here is an example of this:
$stomp->send(
"destination" => "/queue/test",
"body" => "hello world!",
"content-length" => "",
);
ENCODING
The STOMP 1.0 specification does not define which encoding should be used to serialize frames. So, by default, this module assumes that what has been given by the user or by the server is a ready-to-use sequence of bytes and it does not perform any further encoding or decoding.
However, for convenience, three global variables can be used to control encoding/decoding.
If $Net::STOMP::Client::Frame::UTF8Header is set to true, the module will use UTF-8 to encode/decode the header part of the frame.
The STOMP 1.1 specification states that UTF-8 encoding should always be used for the header. So, for STOMP 1.1 connections, $Net::STOMP::Client::Frame::UTF8Header defaults to true.
If $Net::STOMP::Client::Frame::BodyEncode is set to true, the module will use the content-type
header to decide when and how to encode/decode the body part of the frame.
The STOMP 1.1 specification states that the content-type
header defines when and how the body is encoded/decoded. So, for STOMP 1.1 connections, $Net::STOMP::Client::Frame::BodyEncode defaults to true. As a consequence, if you use STOMP 1.1 and supply an already encoded body, you should set $Net::STOMP::Client::Frame::BodyEncode to false to prevent double encoding.
If $Net::STOMP::Client::Frame::StrictEncode is true, all encoding/decoding operations will be stricter and will report a fatal error when given malformed input. This is done by using the Encode::FB_CROAK flag instead of the default Encode::FB_DEFAULT.
N.B.: Perl's standard Encode module is used for all encoding/decoding operations.
MESSAGING ABSTRACTION
If the Messaging::Message module is available, the following methods are available:
- messagify()
-
transform the frame into a Messaging::Message object
- demessagify(MESSAGE)
-
transform the given Messaging::Message object into a Net::STOMP::Client::Frame object (class method)
Here is how they could be used:
# frame to message
$frame = $stomp->wait_for_frames(timeout => 1);
if ($frame) {
$message = $frame->messagify();
...
}
# message to frame
$frame = Net::STOMP::Client::Frame->demessagify($message);
$stomp->send_frame($frame);
COMPLIANCE
STOMP 1.0 has several ambiguities and this module does its best to work "as expected" in these gray areas.
STOMP 1.1 is much better specified and this module should be fully compliant with the STOMP 1.1 specification with two exceptions:
- invalid encoding
-
by default, this module is permissive and allows malformed encoded data (this is the same default as the Encode module itself); to be strict, set $Net::STOMP::Client::Frame::StrictEncode to true (as explained above)
- header keys
-
by default, this module allows only "reasonable" header keys, made of alphanumerical characters (along with
_
,-
and.
); to be able to use any header key (like the specification allows), set $Net::STOMP::Client::Frame::HeaderNameRE toq/[\d\D]+/
.
So, to sum up, here is what you can add to your code to get strict STOMP 1.1 compliance:
$Net::STOMP::Client::Frame::StrictEncode = 1;
$Net::STOMP::Client::Frame::HeaderNameRE = q/[\d\D]+/;
FRAME CHECKING
Net::STOMP::Client calls the check() method for every frame about to be sent and for every received frame.
The check() method verifies that the frame is well-formed. For instance, it must contain a command
made of uppercase letters.
The global variable $Net::STOMP::Client::Frame::CheckLevel controls the amount of checking that is performed. The default value is 2.
- 0
-
nothing is checked
- 1
-
the frame must have a good looking command
the header keys must be good looking and their value must be defined
- 2
-
the level 1 checks are performed
the frame must have a known command
the presence/absence of the body is checked; for instance, body is not expected for a "CONNECT" frame
the presence of mandatory keys (e.g. "message-id" for a "MESSAGE" frame) is checked
for known header keys, their value must be good looking (e.g. the "timestamp" value must be an integer)
- 3
-
the level 2 checks are performed
all header keys must be known/expected
A violation of any of these checks trigger an error in the check() method.
SEE ALSO
Net::STOMP::Client::Debug, Net::STOMP::Client::OO, Messaging::Message, Encode.
AUTHOR
Lionel Cons http://cern.ch/lionel.cons
Copyright CERN 2010-2012
3 POD Errors
The following errors were encountered while parsing the POD:
- Around line 1016:
Expected text after =item, not a number
- Around line 1030:
Expected text after =item, not a number
- Around line 1059:
Expected text after =item, not a number