Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Re^4: WebSocket idle

by noxxi (Pilgrim)
on Jan 21, 2018 at 07:29 UTC ( [id://1207619]=note: print w/replies, xml ) Need Help??


in reply to Re^3: WebSocket idle
in thread WebSocket idle

> That sample code is where my code changes came from

Please look closer at the example code in IO::Socket::SSL you've based your code from. The example code is specifically dealing with the case that there are still buffered data (using pending) before calling can_read again. Your code misses this part. While the code then will work for cases where each websocket frame is in its own SSL frame it will spuriously fail in case multiple websocket frame are contained in one SSL frame.

> Before I made the change, it would get caught in a loop without reading any new data, I'm guessing because SSL needed to be renegotiated like I read in the doc I did find...

In your first code you made the socket non-blocking but then did not check for the socket to be readable at all (can_read) and instead run a busy loop where it always tried to read from the socket and most times immediately failed with EAGAIN since no data where available on the socket. Adding the can_read fixed this but introduced the problem that you don't deal properly with multiple websocket frames inside a single SSL frame. The part about renegotiation instead (i.e. dealing with SSL_WANT_WRITE) is probably unused in most cases since usually no renegotiation will happen on the socket.

Replies are listed 'Best First'.
Re^5: WebSocket idle
by chris212 (Scribe) on Jan 22, 2018 at 15:48 UTC

    I don't understand. Why would multiple websocket frames in one SSL frame cause the code to fail? Why would $ept->get_next_message() not read each websocket frame even if can_read is called while there is more data buffered/pending? Also, before using select, $ept->get_next_message() did not immediately fail most times because there is always more data to read after sleeping for a second. I don't rely on can_read to know when data is available, I rely on $ept->get_next_message().

    Yes, if there is no data buffered/pending, then $ept->get_next_message() will return undef. That is by design. When that happens, it will call somethinghard. Unless we already called it since parsing the last websocket frame, in which case we will sleep for 100ms and there will probably be more data by then.

    Maybe there is something more efficient I can do with the select instead of a sleep? I can't read 1 byte like in that example code because then $ept->get_next_message() will be missing that data when it tries to read the next frame from the socket, right? Only the remaining data from that SSL frame after that byte will still be in the socket buffer? Maybe I should do a $sel->can_read(1) to block for up to a second until there is more data? That might be cleaner, but it shouldn't fail without it.

    It is a little difficult trying to convert that example to my code where I don't actually read the data directly from the socket, but through get_next_message.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1207619]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (4)
As of 2024-03-29 14:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found