Service Documentation
Overview
The chat service is a chat service developed based on the chat protocol, which supports encrypted communication based on rooms and events. At the same time, it supports federated cross-service node communication and point-to-point audio and video calls based on webrtc.
Communication across service nodes
{ Chat client A } { Chat client B }
^ | ^ |
| events | Client-Server API | events |
| V | V
+------------------+ +------------------+
| |---------( HTTP )---------> | |
| homeserver | | homeserver |
| |<--------( HTTP )---------- | |
+------------------+ Server-Server API +------------------+
History Synchronisation
(Federation)
Basic Concepts
Servername (virtual domain name)
servername is the virtual domain name (domain) of the chat service, and together with the user's wallet address constitutes the user ID
Users
Each client is associated with an account, which is used as the unique identification of the chat system, that is, userID. This account is associated with the homeserver to form a space-separated account, which looks like:
@localpart:domain
Devices
The concept of a device is defined in the chat system, which can be a desktop client, some browsers, an Android device or an iPhone, etc. (currently only Android devices are open). A chat system device is associated with a real physical device or mobile application.
The device is mainly used to manage the key used for end-to-end encryption (each device can get its own copy of the decryption key), and at the same time provide assistance when other devices with the same account are connected.
When a user uses the client for the first time, the client registers itself as a new device. Different devices are identified by device ID (device_id), which is unique to each user. Users can define a human-readable device name for the device, which is used for them to manage the device.
Events
All data exchange in the chat is based on event events. Client behavior is defined through events, and each event has a type attribute to distinguish data types. Each event type must be globally unique, Follow the naming rules of the Java namespace, for example, m.room.message represents the message event in the room.
Event Graphs
All event data exchanges in the room are stored in a directed acyclic graph called Event Graphs. Each event in the graph is arranged in chronological order.
Typically, an event has only one parent: the latest message in the room at the time the message was sent. However, homeservers may legitimately race with each other in sending messages, resulting in multiple successors to a single event. Therefore, the next event added to the graph will have multiple parents. Every event graph has a root event with no parent event.
To sort and simplify chronological comparisons between events in the graph, the home server maintains a deep metadata field on each event. An event's depth is a positive integer strictly greater than the depth of any of its parent events. Root events should have a depth of 1. Therefore, if one event precedes another, its depth must be strictly less than 1.
Room structure
A room is a conceptual place where users can send and receive events. Events are sent to a room where all participants with sufficient access will receive the event. Rooms are uniquely identified internally by a "room ID", which has the following form:
!room_id:domain # room_id: a 16-bit random string
Each room has only one room ID. While room IDs do contain domains, it is only used for global namespace room IDs. The room is not in the specified domain.
The conceptual diagram below shows an m.room.message event being sent to room !qporfwt:daodst.com:
{ @alice:daodst.com } { @bob:example.org }
| ^
| |
[HTTP POST] [HTTP GET]
Room ID: !qporfwt:daodst.com Room ID: !qporfwt:daodst.com
Event type: m.room.message Event type: m.room.message
Content: { JSON object } Content: { JSON object }
| |
V |
+------------------+ +------------------+
| homeserver | | homeserver |
| daodst.com | | example.org |
+------------------+ +------------------+
| ^
| [HTTP PUT] |
| Room ID: !qporfwt:daodst.com |
| Event type: m.room.message |
| Content: { JSON object } |
`-------> Pointer to the preceding message ------`
PKI signature from daodst.com
Transaction-layer metadata
PKI Authorization header
....................................
| Shared Data |
| State: |
| Room ID: !qporfwt:daodst.com |
| Servers: daodst.com, example.org |
| Members: |
| - @alice:daodst.com |
| - @bob:example.org |
| Messages: |
| - @alice:daodst.com |
| Content: { JSON object } |
|....................................|
The federation mechanism maintains a shared data structure for each room among multiple homeservers. The data is divided into message events and status events.
Messaging Events: These describe transient "one-off" activity within the room, such as instant messages, VoIP call setup, file transfers, etc. They generally describe communication activities.
State Events: These describe updates to a given persistent information ("state") associated with a room, such as the room's name, subject, membership, participating servers, etc. The state is modeled as a lookup table of key/value pairs per room, where each key is a tuple of state_key and the event type. Each state event updates the value for the given key.
The room state at a given point is computed by considering all events in the graph preceding and including the given event. In cases where events describe the same state, the merge conflict algorithm is applied. The state resolution algorithm is transitive and does not depend on server state, since it must always select the same event, regardless of the server or the order in which the events were received. Events are signed by the origin server (signature includes parent, type, depth and payload hash) and pushed to participating servers in the room via federation, currently using a full mesh topology. Servers can also request backfill events from other servers participating in the room through federation.
Room Aliases
Each room can also have multiple "room aliases", as follows:
#room_alias:domain
The room alias "points to" the room ID, which is the human-readable label used to advertise and discover the room. The room ID pointed to by the alias can be obtained by accessing the specified domain. Note that the mapping from room aliases to room IDs is not fixed and may change over time to point to different room IDs. Therefore, clients should resolve the room alias to a room ID once, and then use that ID in subsequent requests.
When resolving a room alias, the server will also respond with a list of servers in the room that are available to join.
HTTP GET
#matrix:example.org !aaabaa:daodst.com
| ^
| |
_______V____________________|____
| example.org |
| Mappings: |
| #matrix >> !aaabaa:daodst.com |
| #golf >> !wfeiofh:sport.com |
| #bike >> !4rguxf:daodst.com |
|________________________________|
Identity
Users in Matrix are identified by their Matrix User ID. However, it is also possible to use existing 3rd party ID namespaces to identify Matrix users. The matrix "identity" describes the user ID and any other existing IDs in the third-party namespace linked to their account. Matrix users can link third-party IDs (3PIDs) such as email addresses, social networking accounts, and phone numbers to their user IDs. Linking 3PIDs creates a mapping from 3PIDs to user IDs. Matrix users can then use this map to discover the user IDs of their contacts. To ensure that the mapping from 3PIDs to user IDs is authentic, a globally federated cluster of trusted "Identity Servers" (ISs) is used to verify the 3PIDs and to save and replicate the mappings.
In order for a client application to be part of the Matrix ecosystem, the use of IS is not required. However, without a client there will be no way to use 3PID to look up the user ID.
Private User Data
Users can also store arbitrary private key/value data in their accounts -- such as client preferences or server configuration settings lacking any other dedicated APIs. The API is symmetric with the management profile data.