The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

WebSocket::Connection - WebSocket Server Connection

SYNOPSIS

    use WebSocket qw( :ws );
    use WebSocket::Connection;
    my $conn = WebSocket::Connection->new(
        do_pong         => \&pong,
        max_recv_size   => 65536,
        max_send_size   => 65536,
        nodelay         => 1,
        on_binary       => \&on_binary_message,
        on_disconnect   => \&on_close,
        on_handshake    => \&on_handshake,
        on_origin       => \&on_origin,
        on_ping         => \&on_ping,
        on_pong         => \&on_pong,
        on_ready        => \&on_ready,
        on_utf8         => \&on_utf8_message,
        # required
        server          => $websocket_server_object,
        # required
        socket          => $net_socket_object,
    ) || die( WebSocket::Connection->error, "\n" );

    $conn->disconnect( WS_INTERNAL_SERVER_ERROR, 'Something bad happened' );

VERSION

    v0.1.3

DESCRIPTION

Class initiated by WebSocket::Server for each connection received.

This class object is instantiated by "start" in WebSocket::Server upo accepting a new connection. The server then calls "recv" and goes through various phases:

1. Reads the initial client request
2. Parse the handshake data sent by the client with WebSocket::Handshake::Server
3. Calls the "on_origin" callback, if any, passing it the current connection object, the origin URI object

It checks the returns value from that callback and returns an HTTP 403 error (Forbidden) if the callback returned a defined, but false value.

It will also return an HTTP 408 error (Timeout) if the callback fails to respond within 2 seconds.

If the callback dies, it will be caught and an HTTP 500 error (Internal Server Error) will be returned with a generic message.

4. Performs check of the protocol version submitted by the client.
5. If any extension was submitted by the client, it performs check for supported extensions.
6. It calls the "on_handshake" callback, if any, providing it with the current connection object, and the handshake object, and traps any fatal error.

If a fatal error occurred, "recv" returns a WebSocket::Exception back to the "start" in WebSocket::Server, which would end the server connection.

If you want to inspect the initial HTTP headers, this is the phase to do it in. You can use "handshake":

    $conn->on( handshake => sub
    {
        my( $conn, $hs ) = @_;
        # Will print out the entire HTTP request sent by the client
        say $hs->request->as_string;
        # or
        say $conn->handshake->request->as_string;
    });

See WebSocket::Request for more on this.

7. Sends out the Hanshake response
8. Calls the "on_ready" callback, if any, passing it the current connection object, and traps any fatal error.

If a fatal error occurs during the callback, it will be caught and only a warning will be issued if warnings are enabled with use warnings in your code.

CONSTRUCTOR

new

Instantiate a new WebSocket::Connection object. It takes an hash or hash reference of options. Each option matches their corresponding method described below. See each of their documentation for more information.

METHODS

disconnect

    $conn->disconnect( WS_INTERNAL_SERVER_ERROR, 'Something bad happened' );

Provided with a code and a reason, and this will disconnect from the WebSocket and terminate the client connection.

It returns the current object.

disconnected

Set or get a boolean value representing the connection status to the remote client socket.

There are 2 status: disconnecting and disconnected. The former is set when the server has issued a disconnection message to the remote client and is waiting for the client to acknowledge it, as per the WebSocket protocol, and the latter is set when the connection is effectively shut down.

disconnecting

Set or get the boolean value indicating the connection is disconnecting.

do_pong

Set or get the code reference used to issue a pong. By default this is set to "pong"

frame

Returns the connection frame object.

handshake

Set or get the handshake object (WebSocket::Handshake::Server)

This object is instantiated upon instantiation of connection object, so there is no need to create it.

http_error

    $conn->http_error( 426 );
    $conn->http_error( 426, "Upgrade Required" );
    $conn->http_error( 426, "Upgrade Required", "Oh no!" );
    $conn->http_error( 426, "Upgrade Required", "Oh no!", [] );
    $conn->http_error( 426, "Upgrade Required", "Oh no!",
        HTTP::Headers->new(
            Content_Language => "en_GB",
            Cache_Control    => "no-cache"
        )
    );
    $conn->http_error( 400, status => "Bad Request", message => "You missed something in your request" );
    $conn->http_error( 400, {
        status => "Bad Request",
        message => "You missed something in your request"
    });
    $conn->http_error(
        code => 400,
        status => "Bad Request",
        message => "You missed something in your request"
    );
    $conn->http_error({
        code => 400,
        status => "Bad Request",
        message => "You missed something in your request"
    });

Provided with an http status code, an optional status line, some optional content and some optional headers and this will push out on the socket the server error.

You can also provide those parameters as an hash or hash reference.

This method is meant to respond to the client handshake with a proper http error when required, such as if the version or host is missing in the request.

It will return an error if this method is called after a successful handshake has occurred. Otherwise, it returns the return value from "syswrite" in perlfunc which is the number of bytes writen

ip

Set or get the remote ip address of the client connected.

is_ready

Returns true once the handshake has been performed, false otherwise.

max_recv_size

Set or get the maximum bytes that can be received in one time.

max_send_size

Set or get the maximum bytes that can be sent in one time.

metadata

Sets or gets an arbitrary hash reference of data.

This is useful if you want to associate some properties with the connection.

needs_ssl

Returns true if the server is using ssl, false otherwise.

nodelay

Set the client socket option TCP_NODELAY to true or false.

Returns the currently set boolean value.

on

Provided with an hash or hash reference of event name and core reference pairs and this will set those event handlers.

For acceptable event name, check out the supported methods starting with on_. For example: binary, disconnect, handshake, origin, pong, ready, utf8

It returns the current object.

on_binary

Set or get the code reference that is triggered when a binary message is received from the client.

The event handler is then passed the current connection object and the binary message itself.

Any fatal error occurring in the callback are caught using try-catch with (Nice::Try), and if an error occurs, this method will raise a warning if warnings are enabled.

on_disconnect

Set or get the code reference that is triggered when the connection is closed.

The event handler is then passed the current connection object, the code and the possible reason for the disconnection.

Any fatal error occurring in the callback are caught using try-catch with (Nice::Try), and if an error occurs, this method will raise a warning if warnings are enabled.

on_handshake

Event handler called after the handshake between the client and the server has been performed.

The handler is passed this connection object (WebSocket::Connection) and the handshake object (WebSocket::Handshake)

You can get the requested uri using "request_uri", which will return a URI object.

Any fatal error occurring in the callback are caught using try-catch with (Nice::Try), and if an error occurs, this method will set an error and return undef or an empty list depending on the context.

on_origin

Event handler called during the handshake between the client and the server. This is a convenient handler so that the caller can be called with the client submitted origin and decide to accept it by returning true, or reject it by return false.

The callback is provided with this connection object, the origin URI object and the handshake object (WebSocket::Handshake)

If the callback returns a defined, but false value, the origin will be rejected as invalid (403).

A defined but false value could be an empty string or 0. This is designed in case when you do not waant to reply to the server's ping and thus inform it the client is still there.

Any fatal error occurring in the callback are caught using try-catch with (Nice::Try), and if an error occurs, this method will set an error and return undef or an empty list depending on the context.

on_ping

A code reference that will be triggered when a ping is received from the WebSocket client.

The current connection object, and the possible message, if any, are passed as arguments to the event handler.

If the callback returns a defined, but false value, no pong will be issued in reply. A defined but false value could be an empty string or 0. This is designed in case when you do not waant to reply to the server's ping and thus inform it the client is still there.

See "on_ping" and Mozilla documentation on ping and pong

See also "do_pong" to set the code reference to perform a pong

Any fatal error occurring in the callback are caught using try-catch with (Nice::Try), and if an error occurs, this method will raise a warning if warnings are enabled.

on_pong

A code reference that will be triggered when a pong is received from the WebSocket client, most likely as a reply to our initial ping.

The event handler is then passed the current connection object, and a possible message associated, if any.

See "on_ping" and Mozilla documentation on ping and pong

See rfc6455 for more on this

Any fatal error occurring in the callback are caught using try-catch with (Nice::Try), and if an error occurs, this method will raise a warning if warnings are enabled.

on_ready

Event handler called when the connection is ready.

The event handler is then passed the current connection object.

Any fatal error occurring in the callback are caught using try-catch with (Nice::Try), and if an error occurs, this method will raise a warning if warnings are enabled.

on_utf8

Event handler called when a text message is received from the client.

The event handler is then passed the current connection object and the message itself, after having been utf8 decoded.

Any fatal error occurring in the callback are caught using try-catch with (Nice::Try), and if an error occurs, this method will raise a warning if warnings are enabled.

origin

Set or get the origin of the client as set in the request header.

ping

Send a ping to the WebSocket server and returns the value returned by "send". It passes "send" whatever extra argument was provided.

pong

Send a pong to the WebSocket server and returns the value returned by "send". It passes "send" whatever extra argument was provided.

port

Set or get the port number on which the remote client is connected.

recv

Attempts to read chunks of 8192 bytes of data from the client "socket"

If the handshake has not been done yet, it will be performed and the "on_handshake" handler called and the "on_ready" handler as well.

Then, based on the type of data received, it will trigger the "on_binary" for binary message, "on_utf8" for text message, "on_pong" if this is a pong.

request_uri

Returns a URI object representing the uri been requested by the client. For example, a request such as:

    GET /?csrf=7a292e3.1631279571 HTTP/1.1
    Upgrade: WebSocket
    Connection: Upgrade
    Host: localhost:8080
    Origin: http://localhost:8082
    Sec-WebSocket-Key: XcCcHD+q7fmfqRSnPJA9Lg==
    Sec-WebSocket-Version: 13

would result maybe in the uri being wss://localhost:8080/?csrf=7a292e3.1631279571 assuming the server is using SSL.

send

Sends data to the client socket.

Be careful this will return an error if you attempt to send data before the handshake is completed, so you need to check "is_ready"

It returns the number of bytes actually written to the socket.

send_binary

Provided with some data, and this will send the binary message to the client socket.

send_utf8

Provided with some text message, and this will utf8 encode it using "encode" in Encode and send it to the client socket.

server

Set or get the WebSocket::Server object.

status_message

Returns the status message provided by the other party.

shutdown

Terminate the client connection by calling "disconnect" in WebSocket::Server passing it the current connection socket. This does not terminate the server connection itself. For this, check "shutdown" in WebSocket::Server.

socket

Set or get the IO::Socket (or one of its inheriting package such as IO::Socket::INET) object.

subprotocol

Set or get an array object of WebSocket protocols and set the WebSocket header Sec-WebSocket-Protocol.

Returns a Module::Generic::Array object.

See rfc6455 for more information

CREDITS

Graham Ollis for AnyEvent::WebSocket::Client, Eric Wastl for Net::WebSocket::Server, Vyacheslav Tikhanovsky aka VTI for Protocol::WebSocket

AUTHOR

Jacques Deguest <jack@deguest.jp>

SEE ALSO

WebSocket::Server, WebSocket::Client

COPYRIGHT & LICENSE

Copyright(c) 2021-2023 DEGUEST Pte. Ltd.

You can use, copy, modify and redistribute this package and associated files under the same terms as Perl itself.