use IO::Socket::SSL; use Protocol::WebSocket::Frame; use Carp; use Time::HiRes qw(sleep); use Data::Dumper; # Connect to server my $sock = IO::Socket::SSL->new( PeerHost => $self->{server}, PeerPort => $self->{port}, SSL_verify_mode => SSL_VERIFY_NONE, ) or croak($!); binmode($sock); # Switch to unblocking after the SSL initiation $sock->blocking(0); # Write the header my $header = "GET /public/api/blablabla HTTP/1.1\r\n" . "Host: example.com\r\n" . "Upgrade: websocket\r\n" . "Connection: Upgrade\r\n" . "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" . "Sec-WebSocket-Protocol: chat\r\n" . "Sec-WebSocket-Version: 13\r\n" . "Origin: https://cavac.at\r\n" . "\r\n"; $syswrite($sock, $header); # "Parse" the return headers from the server by just skipping over it, hoping for the best ;-) syswrite($sock, $header); my $line = ""; while(1) { my $char; sysread($sock, $char, 1); if(defined($char) && length($char)) { if($char eq "\r") { next; } elsif($char eq "\n") { if($line eq "") { # end of header last; } else { $line = ""; } } else { $line .= $char; } } else { sleep(0.05); # wait a few microseconds for more data } } # Initiate the websocket frame handler my $frame = Protocol::WebSocket::Frame->new(max_payload_size => 500 * 1024 * 1024, masked => 1); # Send a frame { my %request = ( 'request-type' => 'HelloWorld', 'message-id' => 'rand' . int(rand(1_000_000)), 'other-stuff' => 'Hello Welt!', ); my $outframe = $frame->new(buffer => encode_json(\%request), type => 'text', masked => 1)->to_bytes; syswrite($sock, $outframe); } # Handle messages from server while(1) { # Read from socket and append data to the frame parser my $workCount = 0; while(1) { my $char; sysread($sock, $data, 1_000); last if(!defined($data) || !length($data)); $frame->append($data); $workCount++; } # Parse and react to messages from server while(my $data = $frame->next_bytes) { my $msg = decode_json($data); print Dumper($msg); # Just print it out } if(1) { # Other cyclic work you need to do in the program # doSomeStuff(); # $workCount++; } if(!$workCount) { # Nothing happened, just sleep a bit, try again later. Save on CPU cycles sleep(0.05); } }