Net::WebSocket::Endpoint::Server
my $ept = Net::WebSocket::Endpoint::Server->new( parser => $parser_obj, out => $out_fh, #optional, # of pings to send before we send a close max_pings => 5, #optional on_data_frame => sub { my ($frame_obj) = @_; #... }, ); if ( _we_timed_out_waiting_for_read_readiness() ) { $ept->check_heartbeat(); } else { #Only necessary for non-blocking I/O; #it’s meaningless in blocking I/O. #See below for an alternative pattern for use with POE, etc. if ( $ept->get_write_queue_size() ) { $ept->flush_write_queue(); } #This should only be called when reading won’t produce an error. #For example, in non-blocking I/O you’ll need a select() in front #of this. (Blocking I/O can just call it and wait!) $ept->get_next_message(); #INSTEAD OF flush_write_queue(), you might want to send the write #queue off to a multiplexing framework like POE, for which this #would be useful: while ( my $frame = $ept->shift_write_queue() ) { #… do something with $frame->to_bytes() -- probably send it } #Check for this at the end of each cycle. _custom_logic_to_finish_up() if $ept->is_closed(); }
This module, like its twin, Net::WebSocket::Endpoint::Client, attempts to wrap up “obvious” bits of a WebSocket endpoint’s workflow into a reusable component.
The basic workflow is shown in the SYNOPSIS; descriptions of the individual methods follow:
Instantiate the class. Nothing is actually done here. Options are:
parser (required) - An instance of Net::WebSocket::Parser.
parser
out (required) - The endpoint’s output object. An instance of IO::Framed::Write or a compatible class.
out
max_pings (optional) - The maximum # of pings to send before we send a close frame (which ends the session).
max_pings
close
on_data_frame (optional) - A callback that receives every data frame that get_next_message() receives. Use this to facilitate chunking.
on_data_frame
get_next_message()
If you want to avoid buffering a large message, you can do this:
on_data_frame => sub { #... however you’re going to handle this chunk $_[0] = (ref $_[0])->new( payload_sr => \q<>, fin => $_[0]->get_fin(), ); },
The “workhorse” method. It returns a data message if one is available and is the next frame; otherwise, it returns undef.
This method also handles control frames that arrive before or among message frames:
close: Respond (immediately) with the identical close frame. See below for more information.
ping: Send the appropriate pong frame.
pong: Set the internal ping counter to zero. If the pong is unrecognized (i.e., we’ve not sent the payload in a ping), then we send a PROTOCOL_ERROR close frame.
This method may not be called after a close frame has been sent (i.e., if the is_closed() method returns true).
is_closed()
Ordinarily, sends a distinct ping frame to the remote server and increments the ping counter. Once a sent ping is received back (i.e., a pong), the ping counter gets reset.
If the internal ping counter has already reached max_pings, then we send a PROTOCOL_ERROR close frame. Further I/O attempts on this object will prompt an appropriate exception to be thrown.
Returns a Net::WebSocket::Frame::close object or undef to represent the frame that the object has sent, either via the close() method directly or automatically via the internal handling of control messages.
Net::WebSocket::Frame::close
close()
Returns a Net::WebSocket::Frame::close object or undef to represent the frame that the object has received.
DEPRECATED: Returns 1 or 0 to indicate whether we have sent a close frame. Note that sent_close_frame() provides a more useful variant of the same functionality; there is no good reason to use this method anymore.
sent_close_frame()
get_next_message() will automatically send a close frame in response when it receives one. The received close frame is not returned to the application but, like ping and pong, is handled transparently.
Rationale: WebSocket is often billed as “TCP for the web”; however, the protocol curiously diverges from TCP in not supporting “half-close”; a WebSocket connection is either fully open (i.e., bidirectional) or fully closed. (There is some leeway given for finishing up an in-progress message, but this is a much more limited concept.)
This module has several controls for supporting WebSocket extensions:
get_next_message()’s returned messages will always contain a get_frames() method, which you can use to read the reserved bits of the individual data frames.
get_frames()
You can create on_* methods on a subclass of this module to handle different types of control frames. (e.g., on_foo(FRAME)) to handle frames of type foo.) The parser object that you pass to the constructor has to be aware of such messages; for more details, see the documentation for Net::WebSocket::Parser.
on_*
on_foo(FRAME)
foo
To install Net::WebSocket, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Net::WebSocket
CPAN shell
perl -MCPAN -e shell install Net::WebSocket
For more information on module installation, please visit the detailed CPAN module installation guide.