WebSocket-for-Python icon indicating copy to clipboard operation
WebSocket-for-Python copied to clipboard

WantReadError when using ws4py over SSL [updated on 28.11 with details]

Open pomelocorp opened this issue 9 years ago • 1 comments

Hello,

I started from the droid_cherrypy_server.py example, and I am using SSL. For some reason, the server goes into WantReadError.

The issue appears only with Websocket over SSL.

----- UPDATE (28.11.2016)

To summarize:

WANT_READ_ERROR appears when:

  • 4th-5th message in a row in sent (sending data to the server from the phone with a medium size (the size of 500 character string) repeatedly over short intervals (1 second)),
  • A large message is sent for the first time (from the phone to the server).

THE SPECIFIC ERROR STACK TRACE (on the server running droid.py) LOOKS LIKE THIS (at the moment when the large message is sent / or subsequent message is sent in a row):

(IP_ADDR2)- - [26/Oct/2016:16:05:09] "GET /ws HTTP/1.1" 101 - "" ""
[2016-10-26 16:05:09,065] INFO Managing websocket [Local => (IP IP_ADDR1):65006 | Remote => (IP_ADDR2):56645]
[2016-10-26 16:05:27,719] ERROR Failed to receive data
Traceback (most recent call last):
  File "/home/myusername/virtualenv/lawouach/local/lib/python2.7/site-packages/ws4py/websocket.py", line 380, in once
    b = self.sock.recv(self.reading_buffer_size)
  File "build/bdist.linux-x86_64/egg/OpenSSL/SSL.py", line 1304, in recv
    self._raise_ssl_error(self._ssl, result)
  File "build/bdist.linux-x86_64/egg/OpenSSL/SSL.py", line 1149, in _raise_ssl_error
    raise WantReadError()
WantReadError

ATTEMPT 1 (failed):

  • Changing default_buffer_size to something very high like 100000 It did not help (not sure if this change even made sense but I supposed it has to do with the buffer).

ATTEMPT 2 (semi-successful): I updated the code for websocket.py to simply let the OpenSSLError pass:

def once:
        except (socket.error, OSError) as e:
            self.unhandled_error(e)
            return False
        except (pyOpenSSLError) as e:
             pass

With this code, everything works fine (the messages are received and read by the server). However, this is an ugly solution as the issue persists: the error is thrown a couple of times before the message is actually read (cherrypy.log in the except (pyOpenSSLError) indicates a series of errors thrown before the message is finally read).

Does anyone have an idea what is happening and how it resolved or could you please at least point me in the right direction?

Thank you in advance.

pomelocorp avatar Oct 25 '16 18:10 pomelocorp

This site here: http://www.pyopenssl.org/en/stable/api/ssl.html

Says that WantReadError pretty much means that you should retry later, so your second solution is correct.

ws4py didn't used to have anything​ about pyOpenSSL, and I've never encountered this error in older versions, so another possibility would be to go back to using the builtin ssl module by default and falling back as needed to pyOpenSSL?

EternityForest avatar Mar 24 '17 03:03 EternityForest