I think the size of the outgoing message is not really a problem. I have the exact same problem, and setting "max_payload_size" to a larger value does not solve. If this were a problem, you would see an error message with the "to_bytes" framework in the frame. "The payload is too high. Send short messages or increase max_payload_size." When I send a message from a server on Chrome for more than 16k, I donβt see this error (or any other) on the server, yes, I still get "Unable to decode text frame as UTF-8" with "(Opcode - 1)" when the body of the frame message is highlighted in red on the network tab of the Chrome Inspector.
I think it is much more likely that this is a problem with IO :: Socket :: SSL, as I use it as I enforce in Net :: WebSocket :: Server docs. I am wondering if you are fine, or if you see this problem on regular unsolved sockets.
From the IO :: Socket :: SSL docs:
syswrite (BUF, [LEN, [OFFSET]]) These functions behave from outside the same as syswrite in other IO :: Socket objects, for example. this will write no more than LEN bytes to the socket, but there is no guarantee that all LEN bytes are written. It will return the number of bytes written. syswrite will write all the data within a single SSL frame, which means that no more than 16384 bytes, which is the maximum size of an SSL frame, can be written right away.
Net :: WebSocket :: Server :: Connection calls syswrite after creating the frame:
syswrite($self->{socket}, $bytes);
Any ideas on how to deal with this is interesting to me. Perhaps the Frame module should fragment messages below 16k when using SSL, but this would have to be handled in Connection.pm, I would have thought.
UPDATED solution:
it turns out that this is a pretty simple fix if you want to change Connection.pm and put syswrite in a 16k loop. Remembering that SSL frames and WebSocket frames are not the same thing, we just donβt need to overflow the size of the SSL frame. See working solution:
sub send { my ($self, $type, $data) = @_; if ($self->{handshake}) { carp "tried to send data before finishing handshake"; return 0; } my $frame = new Protocol::WebSocket::Frame(type => $type, max_payload_size => $self->{max_send_size}); $frame->append($data) if defined $data; my $bytes = eval { $frame->to_bytes }; if (!defined $bytes) { carp "error while building message: $@ " if $@ ; return; }
I was able to send the 27k json string back to Chrome, which previously did not work with SSL.