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
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(), ); },
out (optional) - The endpoint’s output filehandle. This is only useful if your output is a blocking filehandle; otherwise, you should process the write queue manually via shift_write_queue().
out
shift_write_queue()
before_send_frame (optional) - A callback to be executed before the endpoint sends a ping, pong, or close frame. It receives as an argument the frame that will be sent.
before_send_frame
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 with the identical close frame.
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()
NOTE: If the “out” file handle given to the constructor is in non-blocking mode, then any response frames will be queued rather than sent immediately. That’s where the next method comes in …
Only useful in non-blocking I/O contexts—and at that, probably only useful when you’re not using an event loop, since that loop will likely do its own write buffering.
This will attempt to flush one frame from the write queue. If only part of the message is written, then the next call to this method will resume the output of that message.
This is useful when you have an event loop so that you can feed the frames from the Endpoint object’s queue into the event loop’s write queue. It returns a single frame object, or undef if the queue is empty.
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.
Return 1 or 0 to indicate whether we have tried to send a close frame.
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.