Details
-
Bug
-
Resolution: Done
-
P2: Important
-
5.15.1
-
-
9f6449ef1b6d1e7651f181585f1c35d6722bb87a (qt/qtwebsockets/dev) 42e97a9627655d5d18914a9b9b8f8253b9e88b65 (qt/tqtc-qtwebsockets/tqtc/lts-5.15)
Description
If websocket is closed while receiving large text message and later reopened, next message (that is smaller) will not be received and connection will be closed with "Timeout when reading data from socket" reason.
I've done a bit of research and found out that this is because QWebSocketFrame is not cleared. Normally, frame is processed in this order (I was monitoring m_processingState variable)
- PS_READ_HEADER
- PS_READ_PAYLOAD_LENGTH
- PS_READ_PAYLOAD
- PS_DISPATCH_RESULT
For larger messages, it looks like
- PS_READ_HEADER
- PS_READ_PAYLOAD_LENGTH
- PS_READ_PAYLOAD
- PS_WAIT_FOR_MORE_DATA
- ...
- PS_READ_PAYLOAD
- PS_WAIT_FOR_MORE_DATA
- ...
- PS_READ_PAYLOAD
- PS_DISPATCH_RESULT
If connection is closed with close() or abort() during PS_WAIT_FOR_MORE_DATA state, frame is not cleared. After reconnect, when server sends next message, frame processing starts with PS_READ_PAYLOAD state instead of PS_READ_HEADER. If new message is smaller than previous packet's remaining size, it will still wait for more data and occasionally timeout resulting in connection close.
I was able to fix it by calling frame.clear(); inside QWebSocketDataProcessor::clear() method, yet I'm not sure if it's the proper way to do it.
Please let me know if you need more information