matrix-spec-proposals
matrix-spec-proposals copied to clipboard
MSC2108: Sync over Server Sent Events
Fixes matrix-org/matrix-spec#475 full proposal
Introduction
Currently, Matrix clients use long polling to get the latest state from the server, it becomes an issue when you have a lot of clients because:
- homeserver needs to process a lot of requests, which by the way may return nothing
- it affects network bandwidth, each time client sends request it creates a new HTTP request with headers, cookies and other stuff
- for mobile clients, it spends their cellular Internet and eats money
- when homeserver uses SSL over HTTP (what is recommended), clients are doing again and again the most expensive operation, the TLS handshake
So, instead of long polling I propose to implement sync logic over Server Sent Events(SSE)
Proposal
Server Sent Events(SSE) is a way for servers to push events to clients. It was a part of HTML5 standard and now available in all major web and mobile browsers. It was specifically designed to overcome challenges related to short/long polling. By introducing this technology, we can get the next benefits:
- only 1 persisted connection per client that is kept open "forever".
- SSE is built on top of HTTP protocol, so can be used in communication between servers
- SSE is more compliant with existing IT infrastructure like (Load Balancer, Firewall, etc)
- web and mobile browsers support automatic reconnection and
Last-Event-Id
header out of the box - Matrix protocol is built over HTTP, so SSE should fit good in protocol specification
@stalniy thanks for making this! Just two things need to be done before this is ready for review:
- Please line wrap around 90 characters for easier review
- Please Sign Off on the changes so we are able to merge the proposal later.
Cool! will do in few hours
Added Signed-off-by: Sergii <[email protected]>
to commit message.
Also wrapped lines ~ 90 characters in md
file.
I looked through the changelog of Client-Server communication but cannot find any information of why /events
API was deprecated. Can somebody clarify please?
In terms of SSE, it make sense to publish new events to clients as soon as changes are applied by homeserver, so I guess that most of the times almost all fields of /sync
response will be empty, except 1 which actually contains payload for a single event that represent a change.
So, right now I have doubts whether it make sense to reuse the payload format of /sync
endpoint
Any news?
I looked through the changelog of Client-Server communication but cannot find any information of why /events API was deprecated. Can somebody clarify please?
I'd guess that it's because /sync
can do the same thing, but includes other things too.
In terms of SSE, it make sense to publish new events to clients as soon as changes are applied by homeserver, so I guess that most of the times almost all fields of /sync response will be empty, except 1 which actually contains payload for a single event that represent a change.
So, right now I have doubts whether it make sense to reuse the payload format of /sync endpoint
I don't think it should be too bad, because all of the top-level items (except for next_batch
) in the response can be omitted, so if the payload is just a single event, then only the relevant sections will be included. (I don't think synapse omits empty sections in /sync
, but that's synapse's fault.)
Is there something else I can do to move this forward? Or may I start playing with implementation?
Is there something else I can do to move this forward? Or may I start playing with implementation?
@stalniy: typically review takes a lot longer than we'd like. Implementations help prove that a MSC is needed and serves a purpose, however at this early stage in the proposal process it doesn't make much sense to engineer a perfect implementation. Something which shows the idea as a proposal aide is certainly worthwhile, given the complexity of this proposal (ie: a plain HTML+JS page which dumps JSON bodies into the DOM as a demo). A proper implementation demonstration is required later in the proposal stages.
For the time being, it's best to bring it up every couple months in #matrix-spec:matrix.org to try and solicit review.
Just to add a little note here as well, I decided to write my own little personal testbed for a Server-Sent Events backend as a separate little middleware server in Ruby. https://github.com/ananace/ruby-sinatra-matrix_sse/
It should fit in beside a regular Synapse instance, and just requires a reverse proxy to route /_matrix/client/r0/sync/sse
to it, at which point it will take over and run a /sync
-loop for each request.
Any updates? This would be a very important feature to have, especially for mobile users or areas with very spotty internet connection where a multitude of requests actually hurts performance quite a lot.
This proposal needs to be updated in order to be reviewed again. I’m currently working on my open source project and don’t have time to fix this.
@IngwiePhoenix you can join and help to fix all suggestions and merge back in my repo so we can continue discussion in the same PR.
@stalniy @IngwiePhoenix is there a possibility this MSC will be picked back up? If not, do any of you two know how we can push this MSC forward? I think there'd be a lot of interest for this.
An extension to MSC 3079 to support WebSockets may be an alternative to this proposal. It requires more client and server work, but saves far more bandwidth than this proposal can hope to. Servers can use a proxy initially (so it doesn't help server resources too much) and clients can use HTTP shims/interceptors.
I’ll try to find some time in the next few weeks to update this. However, I’m not a Python expert so would be cool if somebody could implement it eventually
However, I’m not a Python expert so would be cool if somebody could implement it eventually.
I volunteer, I've been working with the synapse codebase for a little while, MXID is @jboi:jboi.nl
if you wanna contact me.
Awesome! @ShadowJonathan I will ping you when this proposal settles down.
Are there any news on the topic? This seems like a very interesting solution, even if personally I would prefer something based on websockets+STOMP
@Polve This will probably be made redundant by MSC3575.
@anoadragon453 I'd personally like to see this MSC (or a followup MSC) transition to "Sliding Sync over Server Sent Events", since there are quite a few places where there is native support for SSE for event streams, which offer both performance and power usage improvements over repeating application-triggered requests. Android being one such example.
[...] since there are quite a few places where there is native support for SSE for event streams, which offer both performance and power usage improvements over repeating application-triggered requests. Android being one such example.
I have no clue whether that's true; but in my opinion, reducing battery usage of Element-Android (while providing instant notifications, without involving Google or other 3rd parties and points of failure) should be considered most important.
@ananace Indeed. It's worth noting that the Sliding Sync MSC explains why it proposes HTTP long-polling over WebSockets (or SSE) which is simply that it's more of an incremental change for today's implementations to transition from Sync v2.
However the MSC also states that the design of the proposal makes it easy to transition to a WebSockets implementation in the future after Sliding Sync is implemented, which is true. I think it'd be slightly more of a leap to SSE, as SSE doesn't define methods for clients to communicate back to the server. In Sliding Sync, the client is constantly asking for specific data (the messages in the room I'm currently looking at, the rooms I can currently see on my screen, etc.) and this information is constantly updating.
So I think you'd end up with SSE + an endpoint the client would keep hitting to get the server to send down different events. And that doesn't seem all that different from the bi-directional pipe that WebSockets provides though.
The document does mention some other advantages to SSE; I'm not sure how much weight those have.
@mcg-matrix None of this will help you if your Element Android client is in the background and your phone has stopped the process. You still need push notifications to get instant notifications.
Check out https://unifiedpush.org/ if you'd like a push solution that doesn't involve Google and is supported by Element Android and other applications.
@anoadragon453 Yeah, an SSE version of sliding sync would be a very different beast from an SSE version of current sync.
I had some design ideas on the subject when in other discussions of MSC3575, and I still think it'd be useful as a transport - just maybe not for the most general use-case.
None of this will help you if your Element Android client is in the background and your phone has stopped the process.
Sounds obvious. :-) I was not trying to find a way out of such a situation.
Check out https://unifiedpush.org/ if you'd like a push solution that doesn't involve Google and is supported by Element Android and other applications.
Thanks, I had heard of UnifiedPush; I wouldn't like any 3rd party or point of failure in addition to Element + Homeserver for my users.