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

PEF::Front::WebSocket - WebSocket framework for PEF::Front

SYNOPSIS

# startup.pl
use PEF::Front::Websocket;
# usual startup stuff...

# $PROJECT_DIR/app/WSTest/WebSocket/Echo.pm
package WSTest::WebSocket::Echo;

sub on_message {
    my ($self, $message) = @_;
    $self->send($message); 
}

1;

DESCRIPTION

This module makes WebSockets really easy. Every kind of WebSocket is in its own module. Default routing scheme is /ws$WebSocketClass. WebSocket handlers are located in $PROJECT_DIR/app/$MyAPP/WebSocket.

Prerequisites

This module requires Coro, AnyEvent and PSGI server that must meet the following requirements.

  • psgi.streaming environment is true.

  • psgi.nonblocking environment is true.

  • psgix.io environment holds a valid raw IO socket object. See PSGI::Extensions.

uwsgi version 2.0.14+ meets all of them with psgi-enable-psgix-io = true.

WEBSOCKET INTERFACE METHODS

on_message($message, $type)

A subroutine that is called on new message from client.

on_drain()

A subroutine that is called when there's nothing to send to client after some successful send.

on_open()

A subroutine that is called each time it establishes a new WebSocket connection to a client.

on_error($message)

A subroutine that is called when some error happens while processing a request.

on_close()

A subroutine that is called on WebSocket close event.

no_compression()

When defined and true then no compression will be used even when it supported by browser and server.

INHERITED METHODS

Every WebSocket class is derived from PEF::Front::Websocket::Base which is derived from PEF::Front::Websocket::Interface. Even when you don't derive your class from PEF::Front::Websocket::Base explicitly, this class will be added automatically to hierarchy.

send($buffer[, $type])

Sends $buffer to client. By default $type is 'text'.

close()

Closes WebSocket.

is_defunct()

Returns true when socket is closed or there's some error on it.

CONFIGURATION

cfg_websocket_heartbeat_interval

WebSocket connection has to be ping-ed to stay alive. This paramters specifies a positive number of seconds for ping interval. Default is 30.

cfg_websocket_max_payload_size

Maximum payload size for incoming messages in bytes. Default is 262144.

cfg_websocket_deflate_minimum_size

Minimum message size for deflate compression. If message size is less than this value then it will not be compressed. Default is 96.

cfg_websocket_deflate_window_bits

WindowBits parameter for deflate compression. Default is 12.

cfg_websocket_deflate_memory_level

MemLevel parameter for deflate compression. Default is 5.

EXAMPLE

 #startup.pl
 use WSTest::AppFrontConfig;
 use PEF::Front::Config;
 use PEF::Front::WebSocket;
 use PEF::Front::Route;

 PEF::Front::Route::add_route(
   get '/' => '/appWs',
 );
 PEF::Front::Route->to_app();
 
 
 # $PROJECT_DIR/app/WSTest/WebSocket/Echo.pm
 package WSTest::WebSocket::Echo;

 sub on_message {
     my ($self, $message) = @_;
     $self->send($message); 
 }

 1;
 
 # $PROJECT_DIR/templates/ws.html
 <html>
 <head>
 <script language="Javascript">
   var s = new WebSocket("ws://[% hostname %]:[% request.port %]/wsEcho");
   s.onopen = function() {
       alert("connected !!!");
       s.send("ciao");
   };
   s.onmessage = function(e) {
       var bb = document.getElementById('blackboard')
       var html = bb.innerHTML;
       bb.innerHTML = html + '<br/>' + e.data;
   };
   s.onerror = function(e) {
       alert(e);
   }
   s.onclose = function(e) {
       alert("connection closed");
   }
   function invia() {
       var value = document.getElementById('testo').value;
       s.send(value);
   }
 </script>
 </head>
 <body>
   <h1>WebSocket</h1>
   <input type="text" id="testo" />
   <input type="button" value="invia" onClick="invia();" />
   <div id="blackboard"
       style="width: 640px; height: 480px; background-color: black; color: white; border: solid 2px red; overflow: auto">
   </div>
 </body>
 </html>
 
 # wstest.ini
 [uwsgi]
 plugins = coroae
 chdir = /$PROJECT_DIR
 logger = file:log/demo.log
 psgi = bin/startup.pl
 master = true
 processes = 4
 coroae = 1000
 perl-no-plack = true
 psgi-enable-psgix-io = true
 uid = $PROJECT_USER
 gid = www-data
 chmod-socket = 664

AUTHOR

This module was written and is maintained by Anton Petrusevich.

Copyright and License

Copyright (c) 2016 Anton Petrusevich. Some Rights Reserved.

This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.