矩阵规范
Matrix定义了一组用于分散通信的开放API,适用于通过全局开放式服务器联合安全发布,持久化和订阅数据,而无需单一控制点。用途包括即时消息(IM),IP语音(VoIP)信令,物联网(IoT)通信以及将现有通信孤岛联系在一起 - 为新的开放式实时通信生态系统提供基础。
要建议更改Matrix规范,请参阅“ 矩阵规格变更建议”中的说明 。
目录
1 Matrix API
该规范包括以下部分:
API | 版 | 描述 |
---|---|---|
客户端 - 服务器API | r0.4.0 | 客户端和服务器之间的交互 |
服务器 - 服务器API | 不稳定 | 服务器之间联合 |
应用服务API | r0.1.0 | 特权服务器插件 |
身份服务API | r0.1.0 | 将第三方ID映射到Matrix ID |
推送网关API | r0.1.0 | 推送Matrix事件的通知 |
该附录包含不针对上述API的一个补充信息。
2 Matrix API简介
警告
Matrix规范仍在不断发展:API尚未冻结,而且此文档正处于正在进行或过时的工作中。我们已尽一切努力清楚地标明仍在最后确定的领域。我们现在正在发布它,因为它足够完整,不仅仅是有用的,并且提供了有关Matrix如何发展的规范参考。我们的最终目标是反映WHATWG的生活标准。
Matrix是一组用于开放式联合即时消息(IM),IP语音(VoIP)和物联网(IoT)通信的开放API,旨在创建和支持新的全球实时通信生态系统。目的是为互联网提供一个开放的分散式pubsub层,以便安全地持久化和发布/订阅JSON对象。该规范是标准化Matrix生态系统的各个组件用于彼此通信的API的持续结果。
Matrix试图遵循的原则是:
- 实用的Web友好API(即REST上的JSON)
- 保持简单和愚蠢
- 提供简单的体系结构,具有最小的第三方依赖性。
- 完全开放:
- 完全开放的联盟 - 任何人都应该能够参与全球Matrix网络
- 完全开放的标准 - 公开记录的标准,没有知识产权或专利许可保留
- 完全开源参考实现 - 自由许可的示例实现,没有IP或专利许可保留
- 赋予最终用户权力
- 用户应该能够选择他们使用的服务器和客户端
- 用户应该控制他们的通信私密程度
- 用户应准确知道其数据的存储位置
- 完全分散 - 对话或整个网络没有单一的控制点
- 从历史中学习,避免重复它
- 尝试采用XMPP,SIP,IRC,SMTP,IMAP和NNTP的最佳方面,同时尽量避免失败
Matrix提供的功能包括:
- 创建和管理完全分布式聊天室,没有单点控制或失败
- 最终一致地加密安全地在联合服务器和服务的全球开放网络上同步房间状态
- 使用(可选)端到端加密在房间中发送和接收可扩展消息
- 由基于功率级别的用户权限系统调解的可扩展用户管理(邀请,加入,离开,踢,禁止)。
- 可扩展的房间状态管理(房间命名,别名,主题,禁令)
- 可扩展的用户配置文件管理(头像,显示名称等)
- 管理用户帐户(注册,登录,注销)
- 使用第三方ID(3PID)(如电子邮件地址,电话号码,Facebook帐户)对Matrix上的用户进行身份验证,识别和发现。
- 可信联盟身份服务器联合:
- 发布PKI的用户公钥
- 将3PID映射到Matrix ID
Matrix的最终目标是成为一个无处不在的消息传递层,用于在人员,设备和服务集之间同步任意数据 - 对于即时消息,VoIP呼叫设置或任何其他需要可靠且持久地从A推送到对象的对象。 B以可互操作和联合的方式。
2.1规格变更建议
要建议更改Matrix规范,请参阅“ 矩阵规格变更建议”中的说明。
3架构
Matrix定义了用于同步可兼容客户端,服务器和服务之间称为“事件”的可扩展JSON对象的API。客户端通常是消息传递/ VoIP应用程序或IoT设备/集线器,并通过使用“客户端 - 服务器API”将通信历史与其“主服务器”同步来进行通信。每个主服务器存储其所有客户端的通信历史记录和帐户信息,并通过与其他主服务器及其客户端同步通信历史记录与更广泛的Matrix生态系统共享数据。
客户端通常通过在虚拟“房间”的上下文中发出事件来彼此通信。房间数据在用户参与给定房间的所有主服务器中复制。因此,没有单个家庭服务器对给定房间拥有控制权或所有权。主服务器将通信历史建模为称为房间“事件图”的事件的部分有序图,其与使用“服务器 - 服务器API”的参与服务器之间的最终一致性同步。在由不同方运行的主服务器之间同步共享对话历史的这个过程称为“联合”。Matrix以一致性为代价优化CAP定理的可用性和分区属性。
例如,对于客户端A向客户端B发送消息,客户端A使用客户端 - 服务器API在其主服务器(HS)上执行所需JSON事件的HTTP PUT。A的HS将此事件附加到其房间事件图的副本,在图的上下文中对消息进行签名以确保完整性。然后,A的HS通过使用服务器 - 服务器API执行HTTP PUT将消息复制到B的HS。B的HS对请求进行身份验证,验证事件的签名,授权事件的内容,然后将其添加到房间事件图的副本中。然后,客户端B通过长期的GET请求从其主服务器接收消息。
数据如何在客户端之间流动 ============================== {Matrix client A} {Matrix client B} ^ | ^ | | 事件| 客户端 - 服务器API | 事件| | V | V + ------------------ + + ------------------ + | | ---------(HTTPS)---------> | | | homeserver | | homeserver | | | <--------(HTTPS)---------- | | + ------------------ + Server-Server API + ------------------ + 历史同步 (联邦)
3.1用户
每个客户端都与一个用户帐户相关联,该帐户在Matrix中使用唯一的“用户ID”进行标识。此ID被命名为分配帐户的主服务器,其格式为:
@localpart:域
有关用户ID结构的完整详细信息,请参阅附录“Identifier Grammar”。
3.2设备
Matrix规范对术语“设备”具有特定含义。作为用户,我可能有多种设备:桌面客户端,一些网络浏览器,Android设备,iPhone等。它们广泛涉及物理世界中的真实设备,但您可能在物理设备上有多个浏览器,或移动设备上的几个Matrix客户端应用程序,每个应用程序都是自己的设备。
设备主要用于管理用于端到端加密的密钥(每个设备都有自己的解密密钥副本),但它们也可以帮助用户管理访问 - 例如,通过撤销对特定设备的访问。
当用户首次使用客户端时,它会将自己注册为新设备。设备的使用寿命可能取决于客户端的类型。Web客户端可能会在注销时丢弃其所有状态,并在每次登录时创建新设备,以确保加密密钥不会泄漏给新用户。在移动客户端中,如果用户是相同的,则在登录会话到期时重新使用该设备可能是可接受的。
设备由device_id标识,device_id在给定用户的范围内是唯一的。
用户可以将人类可读的显示名称分配给设备,以帮助他们管理他们的设备。
3.3事件
通过Matrix交换的所有数据都表示为“事件”。通常,每个客户端动作(例如,发送消息)恰好与一个事件相关。每个事件都有一个类型,用于区分不同类型的数据。 在Java的包命名约定之后,类型值必须是唯一的全局命名空间,例如 com.example.myapp.event。特殊的顶级命名空间m。保留用于Matrix规范中定义的事件 - 例如,m.room.message 是即时消息的事件类型。事件通常在“房间”的背景下发送。
3.4事件图
在房间的上下文中交换的事件存储在称为“事件图”的有向无环图(DAG)中。该图的部分排序给出了房间内事件的时间顺序。图中的每个事件都有一个零个或多个“父”事件的列表,这些事件指的是从创建事件的主服务器的角度来看没有按时间顺序排列的任何先前事件。
通常情况下,事件具有单个父项:房间中发送时的最新消息。但是,家庭服务者在发送消息时可能合法地相互竞争,导致单个事件具有多个后继者。因此,添加到图表中的下一个事件将具有多个父项。每个事件图都有一个没有父项的根事件。
为了订购和简化图表中事件之间的时间顺序比较,主服务器在每个事件上维护深度元数据字段。事件的 深度是一个正整数,严格地大于其任何父母的深度。根事件的深度应为1.因此,如果一个事件在另一个事件之前,那么它必须具有严格更小的深度。
3.5房间结构
房间是用户可以发送和接收事件的概念性场所。事件被发送到房间,并且该房间中具有足够访问权限的所有参与者将接收该事件。客房通过“客房ID”在内部进行唯一标识,其形式如下:
!opaque_id:域
每间客房仅有一间客房。虽然房间ID确实包含域名,但它仅用于全局命名空间房间ID。房间不在指定的域中。
有关房间ID结构的完整详细信息,请参阅附录中的“标识符语法”。
以下概念图显示了发送到房间的 m.room.message事件!qporfwt:matrix.org:
{@alice:matrix.org} {@bob:domain.com} | ^ | | [HTTP POST] [HTTP GET] 房间ID:!qporfwt:matrix.org房间ID:!qporfwt:matrix.org 事件类型:m.room.message事件类型:m.room.message 内容:{JSON object}内容:{JSON object} | | V | + ------------------ + + ------------------ + | homeserver | | homeserver | | matrix.org | | domain.com | + ------------------ + + ------------------ + | ^ | [HTTP PUT] | | 房间ID:!qporfwt:matrix.org | | 事件类型:m.room.message | | 内容:{JSON对象} | `------->指向前面的消息------` 来自matrix.org的PKI签名 事务层元数据 PKI授权标头 ................................... | 共享数据| | 州:| | 房间ID:!qporfwt:matrix.org | | 服务器:matrix.org,domain.com | | 成员:| | - @alice:matrix.org | | - @bob:domain.com | | 消息:| | - @alice:matrix.org | | 内容:{JSON对象} | | ................................... |
联合维护多个主服务器之间的每个房间的共享数据结构。数据分为消息事件和状态事件。
- 消息事件:
- 这些描述了房间中的瞬时“一次性”活动,例如即时消息,VoIP呼叫建立,文件传输等。它们通常描述通信活动。
- 国家活动:
- 这些描述了对与房间相关的给定持久性信息(“状态”)的更新,例如房间的名称,主题,成员资格,参与服务器等。状态被建模为每个房间的键/值对的查找表,每个键都是state_key和事件类型的元组。每个状态事件都会更新给定键的值。
通过考虑图中给定事件之前和包括所有事件来计算给定点处的房间状态。在事件描述相同状态的情况下,应用合并冲突算法。状态解析算法是传递性的,不依赖于服务器状态,因为它必须始终选择相同的事件,而不管服务器或接收事件的顺序。事件由始发服务器签名(签名包括父关系,类型,深度和有效负载哈希)并通过联合推送到房间中的参与服务器,当前使用全网状拓扑。服务器还可以从参与房间的其他服务器请求通过联合回填事件。
3.5.1房间别名
每个房间还可以有多个“房间别名”,如下所示:
#room_alias:域
有关房间别名结构的完整详细信息,请参阅附录中的“标识符语法”。
房间别名“指向”房间ID,是人类可读的标签,通过该标签可以公布和发现房间。可以通过访问指定的域来获取别名指向的房间ID。请注意,从房间别名到房间ID的映射不是固定的,并且可能会随着时间的推移而变化,以指向不同的房间ID。出于这个原因,客户端应该将房间别名解析为房间ID一次,然后在后续请求中使用该ID。
解析房间别名时,服务器还将响应房间中可用于加入的服务器列表。
HTTP GET #matrix:domain.com!aaabaa:matrix.org | ^ | | _______ V ____________________ | ____ | domain.com | | 映射:| | #matrix >>!aaabaa:matrix.org | | #golf >>!wfeiofh:sport.com | | #bike >>!4rguxf:matrix.org | | ________________________________ |
3.6身份
Matrix中的用户通过其Matrix用户ID进行标识。但是,也可以使用现有的第三方ID名称空间来识别Matrix用户。Matrix“Identity”描述了用户ID和链接到其帐户的第三方名称空间中的任何其他现有ID 。Matrix用户可以将第三方ID(3PID)(如电子邮件地址,社交网络帐户和电话号码)链接到其用户ID。链接3PID会创建从3PID到用户ID的映射。然后,Matrix用户可以使用此映射来发现其联系人的用户ID。为了确保从3PID到用户ID的映射是真实的,使用受信任的“身份服务器”(IS)的全局联合集群来验证3PID并持久化并复制映射。
为了使客户端应用程序成为Matrix生态系统的一部分,不需要使用IS。但是,如果没有一个客户端将无法使用3PID查找用户ID。
3.7配置文件
用户可以发布与其帐户相关联的任意键/值数据 - 例如人类可读的显示名称,个人资料照片URL,联系信息(电子邮件地址,电话号码,网站URL等)。
3.8私人用户数据
用户还可以在其帐户中存储任意私钥/值数据 - 例如客户端首选项或缺少任何其他专用API的服务器配置设置。API与管理Profile数据对称。
4规格版本
- 每个API的规范都以rX.YZ格式进行版本控制。
-
- 对X的更改反映了一个重大变化:针对r1.0.0实现的客户端 可能需要更改才能与支持(仅)r2.0.0的服务器 一起使用。
- 对Y的更改表示对现有客户端向后兼容的更改,但不一定是现有服务器:针对r1.1.0实现的客户端无需更改支持r1.2.0的服务器 即可运行 ; 但是需要r1.2.0的客户端可能无法正常使用仅实现r1.1.0的服务器。
- 对Z的改变表示两侧向后兼容的改变。通常,这意味着对规范的澄清,而不是必须实施的变更。