Alice
view release on metacpan or search on metacpan
lib/Alice/HTTP/WebSocket.pm view on Meta::CPAN
package Alice::HTTP::WebSocket;
use strict;
use warnings;
use parent 'Plack::Middleware';
our $VERSION = '0.01';
my $MAGIC = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
sub call {
my ($self, $env) = @_;
$env->{'websocket.impl'} = Alice::HTTP::WebSocket::Impl->new($env);
return $self->app->($env);
}
package Alice::HTTP::WebSocket::Impl;
use Plack::Util::Accessor qw(env error_code version);
use Scalar::Util qw(weaken);
use IO::Handle;
use Protocol::WebSocket::Handshake::Server;
sub new {
my ($class, $env) = @_;
my $self = bless { env => $env }, $class;
weaken $self->{env};
return $self;
}
sub handshake {
my $self = shift;
my $env = $self->env;
my $hs = Protocol::WebSocket::Handshake::Server->new_from_psgi($env);
my $fh = $env->{'psgix.io'};
unless ($fh and $hs->parse($fh)) {
$self->error_code(501);
return;
}
if ($hs->is_done) {
$fh->autoflush;
print $fh $hs->to_string;
$self->version($hs->version);
return $fh;
}
$self->error_code(500);
}
package AnyEvent::Handle::Message::WebSocket;
use Protocol::WebSocket::Frame;
sub anyevent_write_type {
my ($handle, @args) = @_;
Protocol::WebSocket::Frame->new(
version => $handle->{ws_version},
buffer => (join "", @args),
)->to_bytes;
}
sub anyevent_read_type {
my ($handle, $cb) = @_;
$handle->{ws_frame} ||= Protocol::WebSocket::Frame->new(
version => $handle->{ws_version}
);
return sub {
my $frame = $_[0]->{ws_frame};
$frame->append(delete $_[0]{rbuf});
while (defined(my $message = $frame->next)) {
if ($frame->is_close) {
$_[0]->push_write(
Protocol::WebSocket::Frame->new(
type => 'close',
version => $_[0]->{ws_version},
)
);
return;
}
elsif ($frame->is_ping) {
( run in 0.615 second using v1.01-cache-2.11-cpan-39bf76dae61 )