5

I've a web app that connects to a service via WebSockets. This app works fine in Chrome/Firefox for desktop, however Chrome for mobile gives the error:

WebSocket connection to 'ws://192.168.0.11:8080/' failed: One or more reserved bits are on: reserved1 = 0, reserved2 = 1, reserved3 = 0

The server uses a recent version of libwebsockets.

This error occurs during the initial connection, whereupon a moderately large pile of JSON data is sent to the client over multiple 2048 byte frames.

The server exposes several different WebSockets. Some of them fail in other ways too:

Could not decode a text frame as UTF-8.

...and...

Unrecognized frame opcode: 6

A pattern that predicts which should fail and which should succeed has not yet revealed itself.

I suspect some kind of framing issue here. I've reviewed the messages in WireShark and they look correct to me. The headers appear to be correct.

Why would this work in desktop Chrome/Firefox but fail in Chrome for Android?

Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
  • I've placed a capture from WireShark [here for download](https://mega.co.nz/#!m4AG2DjJ!mKMmgYlRyPg0SdianSqMmDi_mdRQEFYNTyDyHjONqzA). – Drew Noakes Mar 30 '14 at 23:37
  • Those errors happen because the client is failing in decoding the frames correctly, so it is trying to make sense from a bunch of bits, and sometimes fails parsing the header, and sometimes the bits look like a header but then the body is just rubbish. Can you force your app to deliver 128 bytes frames all the time and see? It may be an error in how Chrome Android handles the partial frames. This is interesting, please keep the post updated with your findings. – vtortola Mar 31 '14 at 09:23
  • @vtortola, see my answer for updated findings and a workaround. – Drew Noakes Mar 31 '14 at 10:24

1 Answers1

3

The WireShark packet capture shows there are some frames that spill over two TCP packets. The variation of the error messages suggests that random payload is being interpreted as header. I modified my server to make the max packet size 1024 bytes instead of 2048 bytes which suppressed the bug.

I don't know whether this is a bug in Chrome for Android, or whether the desktop version tolerates some violation of the spec that its mobile cousin will not. I suspect the former.

EDIT On my tablet I was also able to address the problem by going into chrome://flags and enabling experimental WebSocket support.

Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
  • That a frame spills over two TCP packets should be irrelevant for the client. I think it is a bug on Android Chrome that does not read frames boundaries correctly. – vtortola Mar 31 '14 at 10:35