# NAME

Net::WebSocket - WebSocket in Perl

# SYNOPSIS

    use Net::WebSocket::Handshake::Client ();
    use Net::WebSocket::HTTP_R ();

    my $handshake = Net::WebSocket::Handshake::Client->new(
        uri => $uri,
    );

    syswrite $inet, $handshake->to_string() or die $!;

    #You can parse HTTP headers however you want;
    #Net::WebSocket makes no assumptions about this.
    my $resp = HTTP::Response->parse($hdrs_txt);

    #If you use an interface that�䏭 compatible with HTTP::Response,
    #then you can take advantage of this convenience function;
    #otherwise you�耱l need to do a bit more work.
    Net::WebSocket::HTTP_R::handshake_parse_response( $handshake, $resp );

    #See below about IO::Framed
    my $iof = IO::Framed->new($inet);

    my $parser = Net::WebSocket::Parser->new($iof);

    my $ept = Net::WebSocket::Endpoint::Client->new(
        parser => $parser,
        out => $iof,
    );

    $iof->write(
        $ept->create_message( 'text', 'Hello, world' )->to_bytes()
    );

    #Determine that $inet can be read from ��

    my $msg = $ept->get_next_message();

    #�� or, if we timeout while waiting for $inet to be ready for reading:

    $ept->check_heartbeat();
    exit if $ept->is_closed();

# BETA QUALITY

This is a beta release. It should be safe for production, but there could
still be small changes to the API. Please check the changelog before
upgrading.

# DESCRIPTION

This distribution provides a set of fundamental tools for communicating via
[WebSocket](https://tools.ietf.org/html/rfc6455).
It is only concerned with the protocol itself;
the underlying transport mechanism is up to you: it could be a file,
a UNIX socket, ordinary TCP/IP, some funky `tie()`d object, or whatever.

Net::WebSocket also �鄄as no opinions�� about how you should do I/O or HTTP
headers. There are too many different ways to accomplish HTTP header
management in particular for it to be sensible for a WebSocket library to
impose any one approach. As a result of this, Net::WebSocket can probably
fit your project with minimal overhead. There are some examples
of how you might write complete applications (client or server)
in the distribution�䏭 `demo/` directory.

Net::WebSocket emphasizes flexibility and lightness rather than the more
monolithic approach in modules like [Mojolicious](https://metacpan.org/pod/Mojolicious).
Net::WebSocket should support anything
that the WebSocket protocol itself can do, as lightly as possible and without
prejudice as to how you want to do it: extensions, streaming, blocking or
non-blocking I/O, arbitrary HTTP headers, etc. The end result should be a
clean, light implementation that will grow (or shrink!) as your needs
dictate.

# OVERVIEW

Here are the main modules:

- [Net::WebSocket::Handshake::Server](https://metacpan.org/pod/Net::WebSocket::Handshake::Server)
- [Net::WebSocket::Handshake::Client](https://metacpan.org/pod/Net::WebSocket::Handshake::Client)

    Logic for handshakes. Every application needs one of these.
    This handles all headers and can also negotiate
    subprotocols and extensions for you.

- [Net::WebSocket::HTTP\_R](https://metacpan.org/pod/Net::WebSocket::HTTP_R)

    A thin convenience wrapper for [HTTP::Request](https://metacpan.org/pod/HTTP::Request) and [HTTP::Response](https://metacpan.org/pod/HTTP::Response),
    CPAN�䏭 �𦨴tandard�� classes to represent HTTP requests and responses.
    Net::WebSocket::HTTP\_R should also work with other classes whose
    interfaces are compatible with these �𦨴tandard�� ones.

- [Net::WebSocket::Endpoint::Server](https://metacpan.org/pod/Net::WebSocket::Endpoint::Server)
- [Net::WebSocket::Endpoint::Client](https://metacpan.org/pod/Net::WebSocket::Endpoint::Client)

    A high-level abstraction to parse input
    and respond to control frames and timeouts. You can use this to receive
    streamed (i.e., fragmented) transmissions as well. You don�脌 have to use
    this module, but it will make your life easier.

- [Net::WebSocket::Parser](https://metacpan.org/pod/Net::WebSocket::Parser)

    Translate WebSocket frames out of a filehandle into useful data for
    your application.

- [Net::WebSocket::Streamer::Server](https://metacpan.org/pod/Net::WebSocket::Streamer::Server)
- [Net::WebSocket::Streamer::Client](https://metacpan.org/pod/Net::WebSocket::Streamer::Client)

    Useful for sending streamed (fragmented) data rather than
    a full message in a single frame.

- Net::WebSocket::Frame::\*

    Useful for creating raw frames. You probably shouldn�脌 call these
    classes directly; instead, use Endpoint�䏭 `create_message()` method.
    But if you want to dig deeply, these will be your bread and butter.
    See [Net::WebSocket::Frame::text](https://metacpan.org/pod/Net::WebSocket::Frame::text) for sample usage.

# IMPLEMENTATION NOTES

## Handshakes

WebSocket uses regular HTTP headers for its handshakes. Because there are
many different solutions around for parsing HTTP headers, Net::WebSocket
is �𦡞gnostic�� about how that�䏭 done. The advantage is that if you�脎e got
a custom solution for parsing headers then Net::WebSocket can fit into
that quite easily.

The liability of this is that you, the library user, must give headers
directly to your Handshake object. (NB: [Net::WebSocket::HTTP\_R](https://metacpan.org/pod/Net::WebSocket::HTTP_R) might
be able to do this for you.)

## Masking

As per [the specification](https://tools.ietf.org/html/rfc6455#section-5.1),
client serializers �𢜛UST�� mask the data randomly, whereas server serializers
�𢜛UST NOT�� do this. Net::WebSocket does this for you automatically,
but you need to distinguish
between client serializers�癳hich mask their payloads�𤤗nd server serializers,
which don�脌 mask.

This module used to do this with [Bytes::Random::Secure::Tiny](https://metacpan.org/pod/Bytes::Random::Secure::Tiny), but
that seems like overkill given that the masking is only there to accommodate
peculiarities of certain proxies. Moreover, TLS is widely available and
[free now besides](https://letsencrypt.org), and it will randomize the data
stream anyway. So, nowadays we just use Perl�䏭 `rand()` built-in.

## Text vs. Binary

Recall that in some languages�鎇ike JavaScript!�𤴆he difference between
�𦭛ext�� and �營inary�� is much more significant than for us in Perl.

## Use of [IO::Framed](https://metacpan.org/pod/IO::Framed)

CPAN�䏭 [IO::Framed](https://metacpan.org/pod/IO::Framed) provides a straightforward interface for chunking up
data from byte streams into frames. It also provides a write buffer for
non-blocking writes, and it (by default) retries on EINTR. You don�脌 have to
use it (which is why it�䏭 not listed as a requirement), but you�耱l need to
provide a compatible interface if you don�脌.

See the demo scripts that use [IO::Framed](https://metacpan.org/pod/IO::Framed) for an example of when you may
need a different solution here.

# EXTENSION SUPPORT

The WebSocket specification describes several methods of extending the
protocol, all of which Net::WebSocket supports:

- The three reserved bits in each frame�䏭 header.
(See [Net::WebSocket::Frame](https://metacpan.org/pod/Net::WebSocket::Frame).) This is used, e.g., in the
[permessage-deflate extension](https://tools.ietf.org/html/rfc7692).
(See below for its implementation in Net::WebSocket.)
- Additional opcodes: 3-7 and 11-15. You�耱l need to subclass
[Net::WebSocket::Frame](https://metacpan.org/pod/Net::WebSocket::Frame) for this, and you will likely want to subclass
[Net::WebSocket::Parser](https://metacpan.org/pod/Net::WebSocket::Parser).
If you�胩e using the custom classes for streaming, then you can
also subclass [Net::WebSocket::Streamer](https://metacpan.org/pod/Net::WebSocket::Streamer). See each of those modules for
more information on doing this.

    **THIS IS NOT WELL TESTED.** Proceed with caution, and please file bug
    reports as needed. (I personally don�脌 know of any applications that
    actually use this.)

- Apportion part of the payload data for the extension. This you
can do in your application.

## permessage-deflate

Net::WebSocket fully supports the permessage-deflate (compression) extension.
See [Net::WebSocket::PMCE::deflate](https://metacpan.org/pod/Net::WebSocket::PMCE::deflate) for details.

# TODO

At this point Net::WebSocket seems to support everything the WebSocket
protocol can (usefully) do, including compression. Please file bug reports
for any issues that may crop up.

- Add more tests.

# SEE ALSO

[Mojolicious](https://metacpan.org/pod/Mojolicious) has a WebSocket implementation. It�䏭 not as complete as
Net::WebSocket, but if you�胩e using Mojolicious, you might try this first.

[Protocol::WebSocket](https://metacpan.org/pod/Protocol::WebSocket) is an older module that supports
pre-standard versions of the WebSocket protocol. It�䏭 similar to this one
in that it gives you just the protocol itself, but it doesn�脌 give you
things like automatic ping/pong/close, classes for each message type, etc.

[Net::WebSocket::Server](https://metacpan.org/pod/Net::WebSocket::Server) implements only server behaviors and
gives you more automation than P::WS.

[Net::WebSocket::EV](https://metacpan.org/pod/Net::WebSocket::EV) uses XS to call [wslay](http://wslay.sourceforge.net).
As of this writing it lacks support for handshake logic.

# REPOSITORY

[https://github.com/FGasper/p5-Net-WebSocket](https://github.com/FGasper/p5-Net-WebSocket)

# AUTHOR

Felipe Gasper (FELIPE)

# COPYRIGHT

Copyright 2018-2019 by [Gasper Software Consulting](http://gaspersoftware.com)

# LICENSE

This distribution is released under the same license as Perl.