Page MenuHomePhabricator

Change notification system implementation not to require Flash
Closed, ResolvedPublic

Assigned To
Authored By
mattflaschen
Nov 14 2014, 8:23 PM
Referenced Files
None
Tokens
"Doubloon" token, awarded by mattflaschen."Love" token, awarded by joshuaspence."Love" token, awarded by qgil.

Description

Use other technologies (such as WebSocket) in Aphlict, so it doesn't require Flash. Reasons:

  • Mobile support (see T5390).
  • Flash still doesn't have good support in free software/open source (though I haven't checked if this works in Gnash).
  • Flash requires serving a socket policy file on port 843, which may be hard to get by corporate proxy (And corporate proxy ops team).

Downsides:

  • Poor/late IE support http://caniuse.com/#feat=websockets (IE >= 10). However, if IE < 10 is a must-have for this feature, something like Socket.IO can be used. That uses WebSocket internally, but has a fallback to COMET for older browsers. The fallback apparently supports even ancient browsers like IE 5.5+

Event Timeline

mattflaschen raised the priority of this task from to Needs Triage.
mattflaschen updated the task description. (Show Details)
mattflaschen added a project: Wikimedia.
mattflaschen added a project: Aphlict.
mattflaschen added a subscriber: mattflaschen.

I could name another reason: interoperability between Firefox and Flash on Windows has been abismal the past couple of years, crashing or hanging plugin-container.exe causing a lot of us to preemptively disable the Flash plugin. Using web sockets (where available) would be a great improvement.

chad triaged this task as Wishlist priority.Nov 14 2014, 8:48 PM

I've been pondering a WebSockets implementation and am going to start mucking around with a prototype. I don't think this task is too difficult. In fact, WebSockets probably gives us a few things for free that we had otherwose hacked into the Flash implementation of Aphlict.

We could use SockJS or similar to emulate the behaviour for IE8/IE9?

I doubt we're likely to add an external just for that. If there is a way to keep flash as fallback (unsupported) while only adding features to the Websocket version, that might be the best course.

I'm sort of OK since Aphlict is optional anyways of just moving outright to Websockets. The downside is less IE support, the upside is total mobile support.

My intention is to keep the actual message structure the same, so using Flash as a fallback should be possible.

Are there are plans to deprecate IE8/IE9 support anytime soon?

Per D11143, there are kind of two separate issues here:

  • Should the client use Flash, WebSockets, or both?
  • Should the server use Node, PHP, or both?

The major unanswered questions for me are:

  • Flash scales well (one pooled connection per machine, across browsers and tabs). What measures can we take to avoid the "100 tabs = 100 connections" problem with WebSockets? From a cursory Googling, it looks like synchronizing over localStorage is the solution? This doubles the amount of HTML5 surface area we're exposed to. Does this actually work, reasonably and reliably, across browsers?
  • Flash can also elect a master tab, so we can play sounds (like chat notifications) once, and publish desktop notifications once, pretty easily. We need to be able to do this. Can we reasonably do it with localStorage?
  • Flash can play sounds pretty reasonably. Can we do that in a nice, cross-browser way without it?
  • Is websockets support in browsers actually reasonable now? The last time I played with it (circa 2010-ish), I could not get it to work at all, and browser debugging tools were hopeless. (I also don't understand the purpose of the crazy handshake and can't find any documentation on what attack it defuses over "X-This-Server-Supports-Websockets: Yes".) For example, do websocket connections show up in browser debugging tools?
  • How large an implementation are we looking at to get WebSockets + localStorage synchronization? Is it more like 100 lines, 1K lines, 10K lines, or what?

If the answers to these questions are "yes", "yes", "yes", "yes", and like "<1K lines", that gives me significant comfort about moving to WebSockets only.

For the server:

  • I am PHP's greatest champion, but seriously suspicious of its ability to fill this role. How many connections can we hold on a reasonable machine with PHP, compared to Node? Are we going to drop from 10K connections per host to 1000, or 100, or 50, or 15? Is the thing going to stay up?

On the client, it would be great if we can swap to websockets, but Flash gives us more than just the connection, and I'm worried we might be trading high complexity with good cross-browser behavior and significant capabilities for even higher complexity, horrible cross-browser behaviors, and uneven capabilities.

On the server, it would maybe-be-sort-of-nice if we can drop the Node dependency, but the risks seem very high there for a small benefit.

I also think it would be fine to drop realtime support for IE8 and IE9. Other HTML5 features (like drag-and-drop uploads, I believe) don't work there, and I think it's reasonable to require users to upgrade to get fancy bells and whistles.

Flash can play sounds pretty reasonably. Can we do that in a nice, cross-browser way without it?

The answer to this question seems to be yes, see D9535. Generally, see T5369 for discussion.

Flash can also elect a master tab, so we can play sounds (like chat notifications) once, and publish desktop notifications once, pretty easily. We need to be able to do this. Can we reasonably do it with localStorage?

The answer to this question seems to be close enough, see D11235. We don't quite have the right primitives but seem to be able to fake our way through things reasonably well on all the major browsers.

For example, do websocket connections show up in browser debugging tools?

In Chrome, there is a dedicated WebSockets tab in the network panel.

How large an implementation are we looking at to get WebSockets + localStorage synchronization? Is it more like 100 lines, 1K lines, 10K lines, or what?

The answer to this question seems to be reasonably small. D11252 has a client websocket implementation in ~100 lines, and D11235 approximately muddles through the localStorage synchronization in ~100 lines. Neither are full-featured, but we're looking at like <1K lines of code rather than >10K.

Is websockets support in browsers actually reasonable now?

The answer to this question seems to be yes. All three browsers did reasonable jobs of showing connection failures and giving reasonable debugging feedback. Safari doesn't seem to show the requests on the network tab, but does print errors to the console. (A few years ago, I recall failures being completely silent.) Chrome and Firefox both print errors and show connections.

In general, WebSockets seems to be far less crazy now than it used to be. When I last implemented it, it was the "Key1/Key2" version, where the signing algorithm is totally insane:

For each of these fields, the server has to take the digits from the
value to obtain a number (in this case 1868545188 and 1733470270
respectively), then divide that number by the number of spaces
characters in the value (in this case 12 and 10) to obtain a 32-bit
number (155712099 and 173347027). These two resulting numbers are
then used in the server handshake, as described below.
..
again expressed as a big-endian 32-bit number, and finally the eight bytes
at the end of the handshake, form a 128 bit string whose MD5 sum is
then used by the server to prove that it read the handshake.

I still don't fully understand why the protocol goes to such lengths to handshake, since it seems to offer no real advantage over, say, browsers dropping connections which include an "X-This-Is-A-Websocket: Yes" header in a response to a form post or XMLHTTPRequest. But the signature algorithm has moved to within the realm of plausibility now, and works in practice, so I'm satisfied with that.

Overall, I'm satisfied that WebSockets aren't a crazy mess anymore, and I think we can move forward to WebSockets only and drop Flash.

Overall, I'm satisfied that WebSockets aren't a crazy mess anymore, and I think we can move forward to WebSockets only and drop Flash.

itshappening