Dancer2...bSocket(3)
π Dancer2::Plugin::WebSocket π¦
okay bestie, welcome to the manual page for Dancer2::Plugin::WebSocket β straight outta the User Contributed Perl Documentation, manual page Dancer2...bSocket(3). It's giving add-a-websocket-interface-to-your-Dancers-app energy, and version 0.3.1 is in the building. no cap.
β¨ NAME β¨
Dancer2::Plugin::WebSocket β add a websocket interface to your Dancers app.
πΈ VERSION πΈ
version 0.3.1
π¦ SYNOPSIS π¦
okay so here's the whole setup, bestie β three files, all the vibes. Start with bin/app.psgi:
#!/usr/bin/env perl
use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/../lib";
use Plack::Builder;
use MyApp;
builder {
mount( MyApp->websocket_mount );
mount '/' => MyApp->to_app;
}
Then config.yml:
plugins:
WebSocket:
# default values
serializer: 0
login: 0
mount_path: /ws
And MyApp.pm:
package MyApp;
use Dancer2;
use Dancer2::Plugin::WebSocket;
websocket_on_message sub {
my( $conn, $message ) = @_;
$conn->send( $message . ' world!' );
};
get '/' => sub {
my $ws_url = websocket_url;
return <<"END";
<html>
<head><script>
var urlMySocket = "$ws_url";
var mySocket = new WebSocket(urlMySocket);
mySocket.onmessage = function (evt) {
console.log( "Got message " + evt.data );
};
mySocket.onopen = function(evt) {
console.log("opening");
setTimeout( function() {
mySocket.send('hello'); }, 2000 );
};
</script></head>
<body><h1>WebSocket client</h1></body>
</html>
END
};
get '/say_hi' => sub {
$_->send([ "Hello!" ]) for websocket_connections;
};
true;
π DESCRIPTION π
Dancer2::Plugin::WebSocket provides an interface to Plack::App::WebSocket and lets you interact with the webSocket connections inside the Dancer app. iykyk.
Plack::App::WebSocket β and therefore this plugin β requires a Plack server that supports the psgi streaming, nonblocking and io. Twiggy is the most popular server fitting the bill. slay.
π CONFIGURATION π
πΈ serializer πΈ
If serializer is set to a "true" value, messages will be assumed to be JSON objects and will be automatically encoded/decoded using a JSON::MaybeXS serializer. If the value of serializer is a hash, it'll be passed as arguments to the JSON::MaybeXS constructor.
plugins:
WebSocket:
serializer:
utf8: 1
allow_nonref: 1
By the way, if you want the connection to automatically serialize data structures to JSON on the client side, you can do something like:
var mySocket = new WebSocket(urlMySocket);
mySocket.sendJSON = function(message) {
return this.send(JSON.stringify(message))
};
// then later...
mySocket.sendJSON({ whoa: "auto-serialization ftw!" });
π mount_path π
Path for the websocket mountpoint. Defaults to "/ws".
Also, the default values block in the SYNOPSIS includes serializer: 0, login: 0, and mount_path: /ws β login is just chillin' there with no extra paragraph, and we're not inventing one. no cap.
π PLUGIN KEYWORDS π
In the various callbacks, the connection object $conn is a Plack::App::WebSocket::Connection object augmented with the Dancer2::Plugin::WebSocket::Connection role. main character energy.
π websocket_on_open sub { ... } π
websocket_on_open sub {
my( $conn, $env ) = @_;
...;
};
Code invoked when a new socket is opened. Gets the new connection object and the Plack $env hash as arguments.
π websocket_on_login sub { ... } π
websocket_on_login sub {
my( $conn, $env ) = @_;
...;
};
Code invoked when a new socket is opened. Gets the connection object and the Plack $env hash as arguments.
Example: return true if user is logged in and the webapp http_cookie is the same as the websocket.
my $login_conn;
my $cookie_name = 'example.session';
hook before => sub {
if (defined cookies->{$cookie_name}) {
$login_conn->{'cookie_id'} = cookies->{$cookie_name}->value;
}
$login_conn->{'login'} = logged_in_user ? 1 : 0;
};
websocket_on_login sub {
my( $conn, $env ) = @_;
my ($cookie_id) = ($env->{'HTTP_COOKIE'} =~ /$cookie_name=(.*);?/g);
if (($login_conn->{'login'}) and ($login_conn->{'cookie_id'} eq $cookie_id)) {
return 1;
} else {
warn "require login";
return 0;
}
};
π websocket_on_close sub { ... } π
websocket_on_close sub {
my( $conn ) = @_;
...;
};
Code invoked when a new socket is opened. Gets the connection object as argument.
π websocket_on_error sub { ... } π
websocket_on_error sub {
my( $env ) = @_;
...;
};
Code invoked when an error is detected. Gets the Plack $env hash as argument and is expected to return a Plack triplet.
If not explicitly set, defaults to:
websocket_on_error sub {
my $env = shift;
return [
500,
["Content-Type" => "text/plain"],
["Error: " . $env->{"plack.app.websocket.error"}]
];
};
π websocket_on_message sub { ... } π
websocket_on_message sub {
my( $conn, $message ) = @_;
...;
};
Code invoked when a message is received. Gets the connection object and the message as arguments.
Note that while websocket_on_message fires for all messages received, you can also be a little more selective. Indeed, each connection, being a Plack::App::WebSocket::Connection object, can have its own (multiple) handlers. So you can do things like:
websocket_on_open sub {
my( $conn, $env ) = @_;
$conn->on( message => sub {
my( $conn, $message ) = @_;
warn "I'm only being executed for messages sent via this connection";
});
};
π websocket_connections π
Returns the list of currently open websocket connections.
π websocket_url π
Returns the full url of the websocket mountpoint.
# assuming host is 'localhost:5000'
# and the mountpoint is '/ws'
print websocket_url; # => ws://localhost:5000/ws
π websocket_mount π
Returns the mountpoint and the Plack app coderef to be used for "mount" in app.psgi. See the SYNOPSIS.
π GOTCHAS π
It seems that closing the socket causes Google's chrome to burp the following to the console:
WebSocket connection to 'ws://...' failed: Received a broken close frame containing a reserved status code.
Firefox seems to be happy, though. The issue is probably somewhere deep in AnyEvent::WebSocket::Server. Since the socket is being closed anyway, I am not overly worried about it.
π SEE ALSO π
This plugin is basically nothing more than a sugar topping atop Plack::App::WebSocket, which is itself AnyEvent::WebSocket::Server wrapped in Plackstic. iconic.
Mojolicious also has nice WebSocket-related offerings. See Mojolicious::Plugin::MountPSGI or <http://mojolicious.org/perldoc/Mojolicious/Guides/Cookbook#Web-server-embedding>. (hi Joel!)
π¦ AUTHOR π¦
Yanick Champoux <yanick@cpan.org>
π COPYRIGHT AND LICENSE π
This software is copyright (c) 2021, 2019, 2017 by Yanick Champoux.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
okay bestie, that's the whole vibe check π«Ά this page is from perl v5.42.0, dated 2021-05-31, manual page Dancer2...bSocket(3) β now go slay your websocket era π
β¨
π¦ where this page comes from
- opensuse-leap 16.0: perl-Dancer2-Plugin-WebSocket 0.3.1-bp160.1.10 Β· Artistic-1.0 OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms