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              
3 1     1   195651 use strict;
  1         1  
  1         46  
4 1     1   4 use warnings;
  1         5  
  1         42  
5 1     1   3 use Future::AsyncAwait;
  1         3  
  1         6  
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 202710 my ($class, %args) = @_;
21              
22             return bless {
23             on_connect => $args{on_connect},
24             on_disconnect => $args{on_disconnect},
25 4         21 }, $class;
26             }
27              
28             sub to_app {
29 4     4 0 5 my ($self) = @_;
30              
31 4         7 my $on_connect = $self->{on_connect};
32 4         5 my $on_disconnect = $self->{on_disconnect};
33              
34 4     4   102 return async sub {
35 4         6 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         10 await $send->({ type => 'websocket.accept' });
40              
41 4 100       233 $on_connect->($scope) if $on_connect;
42              
43             # Echo loop
44 4         5 while (1) {
45 6         53 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         4 });
54             } elsif (exists $event->{bytes}) {
55             await $send->({
56             type => 'websocket.send',
57             bytes => $event->{bytes},
58 1         4 });
59             }
60             } elsif ($event->{type} eq 'websocket.disconnect') {
61 4 100       7 $on_disconnect->($scope, $event->{code}) if $on_disconnect;
62 4         14 last;
63             }
64             }
65 4         24 };
66             }
67              
68             1;
69              
70             __END__