File Coverage

lib/PAGI/App/WebSocket/Echo.pm
Criterion Covered Total %
statement 28 28 100.0
branch 11 14 78.5
condition n/a
subroutine 6 6 100.0
pod 0 2 0.0
total 45 50 90.0


line stmt bran cond sub pod time code
1             package PAGI::App::WebSocket::Echo;
2             $PAGI::App::WebSocket::Echo::VERSION = '0.002000';
3 1     1   191407 use strict;
  1         2  
  1         32  
4 1     1   5 use warnings;
  1         5  
  1         46  
5 1     1   5 use Future::AsyncAwait;
  1         1  
  1         8  
6              
7             =head1 NAME
8              
9             PAGI::App::WebSocket::Echo - Echo WebSocket messages back to sender
10              
11             =head1 SYNOPSIS
12              
13             use PAGI::App::WebSocket::Echo;
14              
15             my $app = PAGI::App::WebSocket::Echo->new->to_app;
16              
17             =cut
18              
19             sub new {
20 4     4 0 195862 my ($class, %args) = @_;
21              
22             return bless {
23             on_connect => $args{on_connect},
24             on_disconnect => $args{on_disconnect},
25 4         19 }, $class;
26             }
27              
28             sub to_app {
29 4     4 0 6 my ($self) = @_;
30              
31 4         8 my $on_connect = $self->{on_connect};
32 4         6 my $on_disconnect = $self->{on_disconnect};
33              
34 4     4   89 return async sub {
35 4         7 my ($scope, $receive, $send) = @_;
36 4 50       11 die "Unsupported scope type: $scope->{type}" if $scope->{type} ne 'websocket';
37              
38             # Accept the connection
39 4         9 await $send->({ type => 'websocket.accept' });
40              
41 4 100       195 $on_connect->($scope) if $on_connect;
42              
43             # Echo loop
44 4         5 while (1) {
45 6         57 my $event = await $receive->();
46              
47 6 100       147 if ($event->{type} eq 'websocket.receive') {
    50          
48             # Echo back - preserve text vs binary
49 2 100       5 if (exists $event->{text}) {
    50          
50             await $send->({
51             type => 'websocket.send',
52             text => $event->{text},
53 1         5 });
54             } elsif (exists $event->{bytes}) {
55             await $send->({
56             type => 'websocket.send',
57             bytes => $event->{bytes},
58 1         24 });
59             }
60             } elsif ($event->{type} eq 'websocket.disconnect') {
61 4 100       8 $on_disconnect->($scope, $event->{code}) if $on_disconnect;
62 4         13 last;
63             }
64             }
65 4         16 };
66             }
67              
68             1;
69              
70             __END__