Long story short: I want to write client code that consumes a webservice, asynchronously receiving data, but need to be able to synchronously make program flow decisions by sending messages to the server.
I have an approach that works but I am certain it’s hacky and The Wrong Way®. It’s achieved by making the websocket transaction variable, $TX, available from outside the transaction. Any guidance on the right way to mix async with sync code here would be much appreciated. Note, the client is all I care about. I provide the server to match just to help test. Modules: Net::WebSocket::Server, Mojo::IOLoop, and Mojo::UserAgent. Thank you!
#!/usr/bin/env perl use utf8; use 5.10.2; use Net::WebSocket::Server; my $Running = 0; Net::WebSocket::Server->new( listen => 8080, tick_period => 1, on_tick => sub { my $server = shift; return unless $Running; $_->send_utf8("Running") for $server->connections; }, on_connect => sub { my ( $server, $connection ) = @_; $connection->on( ready => sub { my $connnection = shift; $connection->send_utf8("Connected… RUN|STOP"); }, utf8 => sub { my ( $connection, $message ) = @_; if ( uc $message eq "RUN" ) { $connection->send_utf8( $Running ? "Already runnin +g" : "Starting to run…"); $Running = 1; } elsif ( uc $message eq "STOP" ) { $connection->send_utf8($Running ? "Stopping…" : "N +ot running"); $Running = 0; } else { $connection->send_utf8("Unknown command: $message" +); } }); }) ->start;
#!/usr/bin/env perl use 5.10.2; use utf8; use strictures; use Mojo::UserAgent; my $ua = Mojo::UserAgent->new; my $TX; # This is what has me thinking this is hacky/kludgy. my $conn = $ua->websocket("ws://localhost:8080/" => sub { my $ua = shift; $TX = shift; say "WebSocket handshake failed!" and return unless $TX->is_websocket; $TX->on(finish => sub { my ( $tx, $code, $reason ) = @_; say "WebSocket closed with status $code."; exit; }); $TX->on(text => sub { my $tx = shift; say "Server > ", +shift; }); }); my @command = qw/ RUN STOP /; Mojo::IOLoop->recurring(5 => sub { my $command = $command[rand@command]; say "Client > $command"; $TX->send($command); }); Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
For: | Use: | ||
& | & | ||
< | < | ||
> | > | ||
[ | [ | ||
] | ] |