Skip to content

Instantly share code, notes, and snippets.

@jberger
Last active July 5, 2018 16:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jberger/17049eaa14069d19c84aca7bc93e5f71 to your computer and use it in GitHub Desktop.
Save jberger/17049eaa14069d19c84aca7bc93e5f71 to your computer and use it in GitHub Desktop.
use Mojo::Base -strict;
use Mojo::IOLoop;
use Mojo::UserAgent;
use Mojo::WebSocket;
use constant DEBUG => $ENV{WSCAT_DEBUG};
my $url = shift || die 'a url is required';
my $reconnect = 1;
my $ping = 1;
my $ua = Mojo::UserAgent->new->inactivity_timeout(0);
sub ws_connect {
$ua->websocket($url => sub {
my ($ua, $tx) = @_;
unless ($tx->is_websocket) {
say STDERR 'Not a websocket' if DEBUG;
Mojo::IOLoop->timer($reconnect => sub { ws_connect() })
if defined $reconnect;
return;
}
say STDERR 'CONNECTED' if DEBUG;
my $stdin = Mojo::IOLoop::Stream->new(\*STDIN);
$stdin->on(read => sub {
my (undef, $bytes) = @_;
$tx->send({ text => $bytes });
});
my $sid = Mojo::IOLoop->stream($stdin);
$tx->on(finish => sub { Mojo::IOLoop->remove($sid) });
$tx->on(message => sub {
my (undef, $msg) = @_;
print $msg;
});
my $pinger;
if ($ping) {
my $waiting = 0;
$tx->on(frame => sub {
my (undef, $frame) = @_;
return unless $frame->[4] eq Mojo::WebSocket::WS_PONG;
say STDERR 'PONG' if DEBUG;
$waiting = 0;
});
$pinger = Mojo::IOLoop->recurring(30 => sub {
if ($waiting) {
say STDERR 'PING timed out' if DEBUG;
return $tx->finish;
}
say STDERR 'PING' if DEBUG;
$waiting = 1;
$tx->send([1, 0, 0, 0, Mojo::WebSocket::WS_PING, ''])
});
}
$tx->on(finish => sub {
say STDERR 'FINISH' if DEBUG;
$stdin->close;
Mojo::IOLoop->remove($pinger) if $pinger;
if (defined $reconnect) {
Mojo::IOLoop->timer($reconnect => sub { ws_connect() });
} else {
Mojo::IOLoop->stop;
}
});
});
}
ws_connect();
Mojo::IOLoop->start;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment