Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much

Re^2: WebSocket idle

by Anonymous Monk
on Jan 03, 2018 at 20:27 UTC ( #1206630=note: print w/replies, xml ) Need Help??

in reply to Re: WebSocket idle
in thread WebSocket idle

I've been using event loops, but I haven't been able to get the loop to triage to my sub when there are no other events. I've only been able to force my sub to run as a periodic event. Here is the code I have now, but it doesn't actually read any frames. Maybe the subscription isn't being sent correctly? It shows the logic I am trying to accomplish, though.

#!/usr/bin/perl use strict; use IO::Socket::SSL; use IO::Framed; use Net::WebSocket::Frame::text; use Net::WebSocket::Parser; use Net::WebSocket::Endpoint::Client; use Net::WebSocket::Handshake::Client (); use Net::WebSocket::HTTP_R (); use HTTP::Response; use JSON::XS; use Data::Dumper; my @prods = qw(BTC-USD LTC-USD ETH-USD); my $host = ''; my $wssurl = "wss://$host/"; my $port = 443; my $inet = IO::Socket::SSL->new("$host:$port") or die "failed connect or ssl handshake: $!\n$SSL_ERROR"; $inet->blocking(0); my $handshake = Net::WebSocket::Handshake::Client->new( uri => $wssurl ); print "REQ HEADERS:\n".$handshake->to_string()."\n"; syswrite $inet, $handshake->to_string() or die $!; my $buffer = ''; my $cnt = 0; my $line = <$inet>; while($line ne "\r\n") { $buffer.= $line; $line = <$inet>; } print "RESP HEADERS:\n$buffer\n"; my $resp = HTTP::Response->parse($buffer); Net::WebSocket::HTTP_R::handshake_consume_response( $handshake, $resp +); #See below about IO::Framed my $iof_r = IO::Framed->new($inet); $iof_r->allow_empty_read(); my $parser = Net::WebSocket::Parser->new( $iof_r ); my $iof_w = IO::Framed->new($inet); my $ept = Net::WebSocket::Endpoint::Client->new( parser => $parser, out => $iof_w, ); my $subscribe = { type => 'subscribe', product_ids => \@prods, channels => ['full'] }; my $payload = encode_json($subscribe); print $payload."\n"; $iof_w->write( Net::WebSocket::Frame::text->new( payload => $payload ) ); while(1) { while(1) { # we are catching up print "get next frame\n"; my $frame = $ept->get_next_message(); print "\$frame = \"$frame\"\n"; last unless($frame); load_frame(decode_json($frame)); } # we are caught up somethinghard(); # catch up again } sub somethinghard { print "something hard\n"; sleep 1; } sub load_frame { my ($frame) = @_; my $data = decode_json($frame); print Dumper($data); }

Replies are listed 'Best First'.
Re^3: WebSocket idle
by haukex (Canon) on Jan 04, 2018 at 10:39 UTC

    What you've shown isn't really the kind of event loop I meant (see e.g. POE) - but that might not be necessary in this case. My understanding from the somewhat sparse documentation (the module is apparently still in beta) and a look at some of the code is that it will return undef if there is currently no message available. Without having the time to test myself at the moment, it sounds to me like this is the "idle" event you are looking for. I don't think you need nested loops either, a single loop with an if/elsif after get_next_message should be enough. Note there is also Time::HiRes that you can use to keep precise track of the timings if you like. And be careful with sleeps, depending on the message frequency, you may not need them at all and you might unnecessarily block your code. And a final nitpick: you seem to be using the term "frame" when you mean "message", I recommend sorting that out so there is no confusion when reading the code.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1206630]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (2)
As of 2018-08-18 02:27 GMT
Find Nodes?
    Voting Booth?
    Asked to put a square peg in a round hole, I would:

    Results (184 votes). Check out past polls.