Merge pull request #352 from matrix-org/rav/kill_old_sync
Remove references to intialSync etc, and rewrite syncing
This commit is contained in:
commit
d8a47dbb5d
1 changed files with 88 additions and 71 deletions
|
@ -702,64 +702,8 @@ considered as a list of events. The server 'linearises' the
|
|||
eventually-consistent event graph of events into an 'event stream' at any given
|
||||
point in time::
|
||||
|
||||
[E0]->[E1]->[E2]->[E3]->[E4]->[E5]->[E6]->[E7]->[E8]->[E9]
|
||||
[E0]->[E1]->[E2]->[E3]->[E4]->[E5]
|
||||
|
||||
Clients can add to the stream by PUTing message or state events, and can read
|
||||
from the stream via the
|
||||
|/initialSync|_,
|
||||
|/events|_,
|
||||
|/rooms/<room_id>/initialSync|_, and
|
||||
|/rooms/<room_id>/messages|_
|
||||
APIs.
|
||||
|
||||
For reading events, the intended flow of operation is to call
|
||||
/_matrix/client/%CLIENT_MAJOR_VERSION%/initialSync, which returns all of the
|
||||
state and the last N events in the
|
||||
event stream for each room, including ``start`` and ``end`` values describing the
|
||||
pagination of each room's event stream. For instance,
|
||||
/_matrix/client/%CLIENT_MAJOR_VERSION%/initialSync?limit=5 might return the
|
||||
events for a room in the
|
||||
rooms[0].messages.chunk[] array, with tokens describing the start and end of the
|
||||
range in rooms[0].messages.start as '1-2-3' and rooms[0].messages.end as
|
||||
'a-b-c'.
|
||||
|
||||
You can visualise the range of events being returned as::
|
||||
|
||||
[E0]->[E1]->[E2]->[E3]->[E4]->[E5]->[E6]->[E7]->[E8]->[E9]
|
||||
^ ^
|
||||
| |
|
||||
start: '1-2-3' end: 'a-b-c'
|
||||
|
||||
Now, to receive future events in real-time on the event stream, you simply GET
|
||||
/_matrix/client/%CLIENT_MAJOR_VERSION%/events with a ``from`` parameter of
|
||||
'a-b-c': in other words passing in the
|
||||
``end`` token returned by initial sync. The request blocks until new events are
|
||||
available or until your specified timeout elapses, and then returns a
|
||||
new paginatable chunk of events alongside new start and end parameters::
|
||||
|
||||
[E0]->[E1]->[E2]->[E3]->[E4]->[E5]->[E6]->[E7]->[E8]->[E9]->[E10]
|
||||
^ ^
|
||||
| |
|
||||
| end: 'x-y-z'
|
||||
start: 'a-b-c'
|
||||
|
||||
To resume polling the events stream, you pass in the new ``end`` token as the
|
||||
``from`` parameter of /_matrix/client/%CLIENT_MAJOR_VERSION%/events and poll again.
|
||||
|
||||
Similarly, to paginate events backwards in order to lazy-load in previous
|
||||
history from the room, you simply
|
||||
GET /_matrix/client/%CLIENT_MAJOR_VERSION%/rooms/<room_id>/messages
|
||||
specifying the ``from`` token to paginate backwards from and a limit of the number
|
||||
of messages to retrieve. For instance, calling this API with a ``from`` parameter
|
||||
of '1-2-3' and a limit of 5 would return::
|
||||
|
||||
[E0]->[E1]->[E2]->[E3]->[E4]->[E5]->[E6]->[E7]->[E8]->[E9]->[E10]
|
||||
^ ^
|
||||
| |
|
||||
start: 'u-v-w' end: '1-2-3'
|
||||
|
||||
To continue paginating backwards, one calls the /messages API again, supplying
|
||||
the new ``start`` value as the ``from`` parameter.
|
||||
|
||||
|
||||
Types of room events
|
||||
|
@ -789,14 +733,56 @@ namespaced for each application and reduces the risk of clashes.
|
|||
Syncing
|
||||
~~~~~~~
|
||||
|
||||
Clients receive new events by "long-polling" the homeserver via the events API.
|
||||
This involves specifying a timeout in the request which will hold
|
||||
open the HTTP connection for a short period of time waiting for new events,
|
||||
returning early if an event occurs. Only the events API supports long-polling.
|
||||
All events which are visible to the client will appear in the
|
||||
events API. When the request returns, an ``end`` token is included in the
|
||||
response. This token can be used in the next request to continue where the
|
||||
last request left off. Multiple events can be returned per long-poll.
|
||||
To read events, the intended flow of operation is for clients to first call the
|
||||
|/sync|_ API without a ``since`` parameter. This returns the most recent
|
||||
message events for each room, as well as the state of the room at the start of
|
||||
the returned timeline. The response also includes a ``next_batch`` field, which
|
||||
should be used as the value of the ``since`` parameter in the next call to
|
||||
``/sync``. Finally, the response includes, for each room, a ``prev_batch``
|
||||
field, which can be passed as a ``start`` parameter to the
|
||||
|/rooms/<room_id>/messages|_ API to retrieve earlier messages.
|
||||
|
||||
You can visualise the range of events being returned as::
|
||||
|
||||
[E0]->[E1]->[E2]->[E3]->[E4]->[E5]
|
||||
^ ^
|
||||
| |
|
||||
prev_batch: '1-2-3' next_batch: 'a-b-c'
|
||||
|
||||
|
||||
Clients then receive new events by "long-polling" the homeserver via the
|
||||
``/sync`` API, passing the value of the ``next_batch`` field from the response
|
||||
to the previous call as the ``since`` parameter. This involves specifying a
|
||||
timeout in the request which will hold open the HTTP connection for a short
|
||||
period of time waiting for new events, returning early if an event occurs. Only
|
||||
the ``/sync`` API (and the deprecated ``/events`` API) support long-polling in
|
||||
this way.
|
||||
|
||||
The response for such an incremental sync can be visualised as::
|
||||
|
||||
[E0]->[E1]->[E2]->[E3]->[E4]->[E5]->[E6]
|
||||
^ ^
|
||||
| |
|
||||
| next_batch: 'x-y-z'
|
||||
prev_batch: 'a-b-c'
|
||||
|
||||
|
||||
Normally, all new events which are visible to the client will appear in the
|
||||
response to the ``/sync`` API. However, if a large number of events arrive
|
||||
between calls to ``/sync``, a "limited" timeline is returned, containing only
|
||||
the most recent message events. A state "delta" is also returned, summarising
|
||||
any state changes in the omitted part of the timeline. The client may therefore
|
||||
end up with "gaps" in its knowledge of the message timeline. The client can
|
||||
fill these gaps using the |/rooms/<room_id>/messages|_ API. This situation
|
||||
looks like this::
|
||||
|
||||
| gap |
|
||||
| <-> |
|
||||
[E0]->[E1]->[E2]->[E3]->[E4]->[E5]->[E6]->[E7]->[E8]->[E9]->[E10]
|
||||
^ ^
|
||||
| |
|
||||
prev_batch: 'd-e-f' next_batch: 'u-v-w'
|
||||
|
||||
|
||||
.. Warning::
|
||||
Events are ordered in this API according to the arrival time of the event on
|
||||
|
@ -805,17 +791,46 @@ last request left off. Multiple events can be returned per long-poll.
|
|||
being received (once per distinct API called). Clients SHOULD de-duplicate
|
||||
events based on the event ID when this happens.
|
||||
|
||||
.. NOTE::
|
||||
|
||||
The ``/sync`` API returns a ``state`` list which is separate from the
|
||||
``timeline``. This ``state`` list allows clients to keep their model of the
|
||||
room state in sync with that on the server. In the case of an initial
|
||||
(``since``-less) sync, the ``state`` list represents the complete state of
|
||||
the room at the **start** of the returned timeline (so in the case of a
|
||||
recently-created room whose state fits entirely in the ``timeline``, the
|
||||
``state`` list will be empty).
|
||||
|
||||
In the case of an incremental sync, the ``state`` list gives a delta
|
||||
between the state of the room at the ``since`` parameter and that at the
|
||||
start of the returned ``timeline``. (It will therefore be empty
|
||||
unless the timeline was ``limited``.)
|
||||
|
||||
In both cases, it should be noted that the events returned in the ``state``
|
||||
list did **not** necessarily take place just before the returned
|
||||
``timeline``, so clients should not display them to the user in the timeline.
|
||||
|
||||
.. admonition:: Rationale
|
||||
|
||||
An early design of this specification made the ``state`` list represent the
|
||||
room state at the end of the returned timeline, instead of the start. This
|
||||
was unsatisfactory because it led to duplication of events between the
|
||||
``state`` list and the ``timeline``, but more importantly, it made it
|
||||
difficult for clients to show the timeline correctly.
|
||||
|
||||
In particular, consider a returned timeline [M0, S1, M2], where M0 and M2 are
|
||||
both messages sent by the same user, and S1 is a state event where that user
|
||||
changes their displayname. If the ``state`` list represents the room state at
|
||||
the end of the timeline, the client must take a copy of the state dictionary,
|
||||
and *rewind* S1, in order to correctly calculate the display name for M0.
|
||||
|
||||
.. TODO-spec
|
||||
Do we ever support streaming requests? Why not websockets?
|
||||
|
||||
When the client first logs in, they will need to initially synchronise with
|
||||
their homeserver. This is achieved via the initial sync API described below.
|
||||
This API also returns an ``end`` token which can be used with the event stream.
|
||||
{{sync_cs_http_api}}
|
||||
|
||||
{{old_sync_cs_http_api}}
|
||||
|
||||
{{sync_cs_http_api}}
|
||||
|
||||
|
||||
Getting events for a room
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -1060,7 +1075,9 @@ Leaving rooms
|
|||
A user can leave a room to stop receiving events for that room. A user must
|
||||
have been invited to or have joined the room before they are eligible to leave
|
||||
the room. Leaving a room to which the user has been invited rejects the invite.
|
||||
Once a user leaves a room, it will no longer appear on the |/initialSync|_ API.
|
||||
Once a user leaves a room, it will no longer appear in the response to the
|
||||
|/sync|_ API unless it is explicitly requested via a filter with the
|
||||
``include_leave`` field set to ``true``.
|
||||
|
||||
Whether or not they actually joined the room, if the room is
|
||||
an "invite-only" room they will need to be re-invited before they can re-join
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue