Apparent blocking behaviour in JavaScript websocke

2020-03-20 01:40发布

问题:

I've run into a real head-scratcher, and I was hoping someone out there could shed some light on my issue.

The application I'm writing is a JS based client for what is essentially a desktop-sharing a service. The service captures images from the desktop, encodes them, as base64 encoded jpegs and sends them over a websocket to the JS client. The client then displays these images (as data URIs), users can move the mouse over the image as well as click on the image, these mouse events are encoded as commands in XML which are put into a queue and serviced on a timer every 15ms, this way the queue can be scrubbed of redundant or duplicate commands before being sent to the service. These commands are then executed (generating click events on the desktop, moving the mouse, etc.), and new desktop images are generated and the cycle continues.

The whole system works extremely well, except for some very inconsistent behaviour on Safari on the iPad. Essentially, when the user moves their finger around the screen, the client seems to block (or possibly de-prioritize) incoming messages on the websocket, in favour of only sending outgoing messages. The way this is manifest is that as you move your finger around, the display will not appear to update as long as you are touching the screen, then once you raise your finger, a flood of image updates will be received by onMessage(), which then get animated to the screen in rapid succession.

Mobile Safari is the only browser that appears to behave in this way, none of the desktop browsers, or any of the Android tablets I've tested appear to show the same behaviour.

I've put logging into the inbound and outbound methods on the websocket, and it confirms the behaviour I've seen. On Safari, I'll get numerous outbound messages in a row, followed by numerous inbound messages, whereas on Android, I'll see the inbound and outbound messages interleaved as you drag your finger around the screen, as a result the display on Android will continue to update as your are dragging your finger around.

The main reason why I suspect the websocket as the culprit is because the client has a fallback mechanism, so that if a browser does not have websocket support, a pair of XHR objects are created (one for inbound and one for outbound) and used instead of the websocket. If I force mobile Safari to use XHR instead of websockets, the problem goes away. In this case only the communication mechanism changes (all of the code for capturing input events and displaying images stays the same).

I realize that this a pretty specific problem, and without code it will be very hard to diagnose, but I opted not to post code simply due to the sheer volume of code in the client.

If anyone has see behaviour similar to what I've described, or know of any potential reasons for this behaviour, I'd be very thankful for your input.

回答1:

Depending on the size of the packets, you could face the problem of 'large' messages, being extremely slow on Safari (both on iPad and desktop). Have you tried desktop Safari?

Have a look at this page, to see comparisons of performance between different browsers.

It could be that this is your problem.