How to write a client program for Net::WebSocket::Server program?

Viewed 427

I have a server program that listens on 9000 port. But I can't find a way to write a client program for that server that connects server at 9000 port. Here is the main part of server program:

use strict;
use warnings;

use Net::WebSocket::Server;
    
my $port = "9000";
my $msg_count = 0;

print "starting server on $port \n\n";

my $count = 2400;

Net::WebSocket::Server->new(
    listen => $port,
    silence_max => 5,

    tick_period => 300,
    on_tick => sub {
        my ($serv) = @_;    
        print "connections >> " . $serv->connections . "\n";    
        print $_->ip() for( $serv->connections() ); print "\n";
        print $_->port() for( $serv->connections() ); print "\n\n";
        $count++;    
    },

    on_connect => sub {
        my ($serv, $conn) = @_;
        $conn->on(   

        handshake => sub {
                my ($conn, $handshake) = @_;
                my $tmp = $handshake->req->origin;
                print "here ... $tmp \n\n";    
        },

            utf8 => sub {
                my ($conn, $msg) = @_;
                my $IP = $conn->ip();
                my $PORT = $conn->port();
                my $SERVER = $conn->server();
                my $SOCKET = $conn->socket();
                my $str = Dumper $SOCKET;

I searched internet and what that sounds understandable to me is the following client program:

use strict;
use warnings;
use IO::Socket::SSL;

my $cl=IO::Socket::SSL->new("http://localhost:9000") or die "error=$!, ssl_error=$SSL_ERROR"; 
if($cl) {
    $cl->connect_SSL or die $@;
    # Something about certificates?
    $cl->syswrite("Command");
    close($cl);
}

But its not working. The error client program generates is as follows:

Expected 'PeerService' at client2.pl line 5.

I am newbie in Socket programming and currently understanding websockets programming in Perl.

Note: I am on windows platform.

I ran the example code suggested https://stackoverflow.com/questions/37318581/simple-perl-websocket-client. It gives error "Can't use an undefined value as a subroutine reference at C:/Strawberry/perl/site/lib/Protocol/WebSocket/Client.pm line 103.":

use strict;
use warnings;
use Protocol::WebSocket::Client;

my $client = Protocol::WebSocket::Client->new(url => 'ws://localhost:9000') or die "$!";
my $reply = "Free\n";
# Sends a correct handshake header
$client->connect or die "$!";

# Register on connect handler
$client->on(
    connect => sub {
        $client->write('hi there');
    }
) or die "$!";

# Parses incoming data and on every frame calls on_read
$client->read($reply);
print "$reply\n";

# Sends correct close header
$client->disconnect;
1 Answers

Please investigate following demo code snippets for WebSocket Server and Client.

Note: please do not forget to alter code to match your server origin (ip address and port)

use strict;
use warnings;
use feature 'say';

use Net::WebSocket::Server;

my $origin = 'http://192.168.1.160:8080';  # server origin
my $port = 8080;

$| = 1;

say "Starting server on $port";

Net::WebSocket::Server->new(
    listen => $port,
    tick_period => 60,
    on_tick => sub {
        my ($serv) = @_;
        my $stamp = 'Server time: ' . scalar localtime;
        $_->send_utf8($stamp) for $serv->connections;
    },
    on_connect => sub {
        my ($serv, $conn) = @_;
        $conn->on(
            handshake => sub {
                my ($conn, $handshake) = @_;
                $conn->disconnect() unless $handshake->req->origin eq $origin;
            },
            ready => sub {
                my ($conn) = @_;
                say "Client: connect IP $conn->{ip} PORT $conn->{port}";
                my $msg = 'Connected server time is ' . scalar localtime . "\n";
                $_->send_utf8($msg) for $conn->server->connections;
            },
            utf8 => sub {
                my ($conn, $msg) = @_;
                say "Client message: $conn->{ip} $msg";
                $_->send_utf8('Server reply: ' . $msg)
                        for $conn->server->connections;
                $conn->disconnect() if $msg eq 'exit';
            },
            binary => sub {
                my ($conn, $msg) = @_;
                $_->send_binary($msg) for $conn->server->connections;
            },
            pong => sub {
                my ($conn, $msg) = @_;
                $_->send_utf8($msg) for $conn->server->connections;
            },
            disconnect => sub {
                my ($conn, $code, $reason) = @_;
                say "Client: disconnect IP $conn->{ip} PORT $conn->{port}";
            },
        );
    },
)->start;

Client

use strict;
use warnings;
use feature 'say';

use IO::Async::Loop;
use Net::Async::WebSocket::Client;

my $HOST = '192.168.1.160';
my $PORT = 8080;

my $loop = IO::Async::Loop->new;

my $client = Net::Async::WebSocket::Client->new(
   on_text_frame => sub {
      my ( $self, $frame ) = @_;
      say $frame;
   },
);

my $input = IO::Async::Stream->new_for_stdin(
    on_read => sub {
        my ( $self, $buffref, $eof ) = @_;

        my $msg;

        $msg = $1 while $$buffref =~ s/^(.*)\n//;

        $client->send_text_frame( $msg );

        $loop->loop_stop if $msg eq 'exit';

        return 0;
    },
);

$loop->add( $client );
$loop->add( $input  );

$client->connect(
   url => "ws://$HOST:$PORT/"
)->then( sub {
    say 'Successfully connected to server';
    $client->send_text_frame( scalar localtime );
})->get;

$loop->run;

say 'Bye, until next time';

exit 0;

References:

Related