NAME

Net::WebSocket::EV - Perl wrapper around Wslay websocket library

DESCRIPTION

Net::WebSocket::EV - websocket module based on Wslay http://wslay.sourceforge.net/. This module uses libev for doing IO.

SYNOPSIS

##### echo server #####

use Net::WebSocket::EV;
use HTTP::Server::EV;
use Digest::SHA1 qw(sha1_base64);

HTTP::Server::EV->new->listen(888, sub {
		my $cgi = $_[0];
		
		$cgi->header({
			STATUS 		=> '101 Switching Protocols',
			Upgrade		=> "websocket",
			Connection	=> "Upgrade",
			"Sec-WebSocket-Accept" 	=> scalar 
				sha1_base64( $cgi->{headers}{"Sec-WebSocket-Key"} . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" ).'=',
		});
		
		$cgi->{self} = $cgi; # circular. Keep object
		
		$cgi->{buffer}->flush_wait(sub {
		
			$cgi->{websocket} = Net::WebSocket::EV::Server->new({
				fh => $cgi->{buffer}->give_up_handle,
				
				on_msg_recv => sub { 
					my ($rsv,$opcode,$msg, $status_code) = @_;
					
					$cgi->{websocket}->queue_msg($msg);
				},
				
				on_close => sub {
					my($code) = @_;
					
					#remove circular
					$cgi->{self} = undef;
					$cgi = undef;
				},
				buffering => 1,
			});
			
		});
},  { threading => 0 });

EV::run;

METHODS

new( { params } )

Can be used as Net::WebSocket::EV::Server->new or Net::WebSocket::EV::Client->new

Params:

fh

Filehandle of socket to use. Socket must be set in non blocking mode.

Net::WebSocket::EV doesn't do handshake, you must do it before calling new().

buffering

If set to 0 - disables buffering. on_msg_recv is always called with empty $msg, use on_frame_recv_* to handle messages. Useful for handling big binary data without buffering it in memory.

Default if not defined : 1

max_recv_size

Max message or frame size, see http://wslay.sourceforge.net/man/wslay_event_config_set_max_recv_msg_length.html

on_msg_recv

This callback is called when library receives complete message. Close messages aren't handled by this callback. When buffering is disabled $msg is always empty

Callback arguments: my ($rsv, $opcode, $msg, $status_code) = @_;

on_close

Called when connection is closed.

Callback arguments: my ($close_code) = @_;

genmask

Used only by Net::WebSocket::EV::Client. Must return $len bytes scalar to mask message. If not specified, then simple rand() mask generator is used.

Callback arguments: my ($len) = @_;

on_frame_recv_start

Called when frame header is received.

Callback arguments: my ($fin, $rsv,$opcode,$payload_length) = @_;

on_frame_recv_chunk

Called when next data portion is received.

Callback arguments: my ($data) = @_;

on_frame_recv_end

Called when message is received. No arguments

queue_msg( message, opcode )

Queue message, opcode is optional default is 1 (text message)

queue_fragmented ( callback, opcode )

Queue fragmented message, opcode is optional, default is 2 (binary message)

Callback arguments: my ($len) = @_;

Callback must return array of two elements ( "scalar $len or less(can be 0) bytes length", status )

Status can be:

WS_FRAGMENTED_DATA - Data chunk, optional status value, you can just return one scalar with data. Wslay will constantly reinvoke callback when it returns WS_FRAGMENTED_DATA. It will let other events run, but you will get 100% cpu load if there is no data to send and your callback always returns WS_FRAGMENTED_DATA with empty scalar while waiting for data. To prevent this use ->stop_write to suspend all IO when there is no more data to send and ->start_write when new portion of data is ready.

WS_FRAGMENTED_ERROR - Error. Don't call callback anymore

WS_FRAGMENTED_EOF - End of message.

wait(cb)

Callback called when send queue becomes empty. If callback isn't specified, then tryes to use Coro::rouse_cb & Coro::rouse_wait to block current coro.

queued_count()

Returns number of messages in send queue

start() and stop()

Start or stop all webosocket IO

start_read() and stop_write()

start_read() and stop_read()

shutdown_read() and shutdown_write()

Disable read or write. There is no way to enable it again, use start_* and stop_* instead

close( status_code, reason_data)

Queue close frame. Status and reason are optional.

Possible atack vector: client can hold connection after receiving close frame and make a lot of connections. So if you want to guaranteed close connection, then call $ws->close() and ->wait until close frame will be sent, then close socket by close($ws->{fh}).