package Cualsea::MessageManager; use v5.30.0; use strict; use warnings; use Encode; use Types::Standard qw/Object HashRef/; use Params::ValidationCompiler qw/validation_for/; use JSON; { my $validator = validation_for( params => { # Ideally this would check the class, but I don't care a lot in this case. socket => { type => Object }, } ); sub new { my $class = shift; # Having a instance soon in the constructor is often useful if a method needs to be called. my $self = bless {}, $class; my %params = $validator->(@_); # This is magically safe using ValidationCompiler. $self->{socket} = $params{socket}; return $self; } } sub _socket { my $self = shift; return $self->{socket}; } sub read_message { my $self = shift; my $socket = $self->_socket; my $len_bytes; my $len; my $message_json; $socket->recv($len_bytes, 4); $len = unpack ('L', $len_bytes); say "Received len $len"; $socket->recv($message_json, $len); say "Received message $message_json"; my $message = decode_json($message_json); print Data::Dumper::Dumper $message; return $message; } { my $validator = validation_for( params => { # I have decided everything should be a HashRef in order to # have a sane in packet metadata support. message => { type => HashRef }, } ); sub write_message { my $self = shift; my %params = $validator->(@_); my $message = $params{message}; my $socket = $self->_socket; my $message_json = encode_json($message); # We will want the len to be calculated over the raw bytes. $message_json = Encode::encode("UTF-8", $message_json); my $len = length $message_json; my $len_str = pack 'L', $len; $socket->send($len_str); say "Sended len $len"; $socket->send($message_json); say "Sended message $message_json"; } } 1