PEF::Front::WebSocket - WebSocket framework for PEF::Front
# 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;
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
.
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
.
A subroutine that is called on new message from client.
A subroutine that is called when there's nothing to send to client after some successful send.
A subroutine that is called each time it establishes a new WebSocket connection to a client.
A subroutine that is called when some error happens while processing a request.
A subroutine that is called on WebSocket close event.
When defined and true then no compression will be used even when it supported by browser and server.
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.
Sends $buffer to client. By default $type is 'text'.
Closes WebSocket.
Returns true when socket is closed or there's some error on it.
- 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.
#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
This module was written and is maintained by Anton Petrusevich.
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.