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!

Sample server and client…

Save and run the server–

#!/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;

Then the client–

#!/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;

In reply to Mixing asynchronous data feed with synchronous program flow control by Your Mother

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.