in reply to Connect to a *secure* websocket server (wss)

It really depends on your needs. I'm mostly used to the server side of things writing cyclic executives, so i'm not sure what event based options for clients are available ;-)

The couple of times i needed a websocket client, i did it "by hand" using Protocol::WebSocket::Frame after connecting via IO::Socket::SSL, because that works well enough for my own cyclic needs.

Connection is easy, unless the W3C has re-defined things yet again. Here's an untested(!) minimal cyclic executive (a "worker") based on some of my existing codebase. I didn't include all that much error handling here, though, to keep the code small.

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); } }

Hope that helps.

PerlMonks XP is useless? Not anymore: XPD - Do more with your PerlMonks XP
Also check out my sisters artwork and my weekly webcomics

Replies are listed 'Best First'.
Re^2: Connect to a *secure* websocket server (wss)
by bliako (Abbot) on Sep 24, 2025 at 14:54 UTC

    cavac thank you for this code. I think I will continue with a high-level module though since Corion solved my problem above, i will continue with that. thank you.