协议中的状态和事件简介

举报
码乐 发表于 2024/02/28 09:01:15 2024/02/28
【摘要】 3 简介这个小系列介绍一些使用中的协议。Matrix是一种用于实时通信的开放协议。它允许使用一个通信服务提供商帐户的用户与使用不同服务提供商的用户进行网络聊天,IP语音和视频通话。Matrix项目在WebRTC 2014年大会暨博览会上赢得了创新奖,并随后在WebRTC 2015年大会暨博览会获得了最佳展示奖。也就是说,它旨在使不同服务提供商之间的实时通信无缝工作,就像使用电子邮件一样。采...

3 简介

这个小系列介绍一些使用中的协议。

Matrix是一种用于实时通信的开放协议。它允许使用一个通信服务提供商帐户的用户与使用不同服务提供商的用户进行网络聊天,IP语音和视频通话。
Matrix项目在WebRTC 2014年大会暨博览会上赢得了创新奖,并随后在WebRTC 2015年大会暨博览会获得了最佳展示奖。
也就是说,它旨在使不同服务提供商之间的实时通信无缝工作,就像使用电子邮件一样。采用该协议的软件有Element.io等。Matrix是联邦宇宙的一部分。

2015年6月22日,Matrix项目负责人马修·霍奇森(Matthew Hodgson)宣布Matrix和IRC网络Freenode完成互联,Freenode中的每一个IRC频道都会有相对应的Matrix聊天室。

3.1.0 在协议中什么是状态?

服务协议的状态(这里说的是即时通讯协议矩阵Matrix)是诸如谁在房间里,房间主题/名称是什么,谁有什么特权级别等。

服务器 跟踪它,以便它可以发现无效事件(例如,由被禁止的用户或权限不足的人发送的事件)。

3.1.1 什么是状态组?

服务器 需要跟踪每个事件发生时的状态。一个状态组
对应一个唯一的状态。数据库表event_to_state_groups保持跟踪
从事件 ID 到状态组 ID 的映射。

考虑以下简化示例:

``
状态组 ID | 状态
_____________________________________________
       1 | 房间里的小李
       2 | 小李在房间里,老王在房间里
       3 | 房间里的老王
 
 
事件编号 | 事件是什么
______________________________________
    1 | 小李发送消息
    3 | 老王加入房间
    4 | 老王发送消息
    5 | 小李离开房间
    6 | 老王发送消息
 
	 
事件编号 | 状态组 ID
_________________________
    1 | 1
    2 | 1
    3 | 2
    4 | 2
    5 | 3
    6 | 3
``

3.1.2 暂存状态(deltas)和前辈是什么?

当一个新的状态事件发生时(例如 老王 加入房间),就会创建一个新的状态组。

但是我们不是从前一个状态组中复制所有状态,而是存储上一组的变化(节省大量存储空间!)。
区别来自前一个状态组被称为暂存状态(“delta”).

所以对于前面的例子,我们将有以下内容(注意只有第 1 行和第 2 行在这一点上有意义):

``
状态组 ID | 上一个状态组 ID | 暂存状态(Delta)
____________________________________________________________
       1 | 无 | 房间里的小李
       2 | 1  | 房间里的老王
       3 | 无 | 房间里的老王
``

那么第 3 行发生了什么?那么 deltas 在服务器中的工作方式是它们只能添加新状态或覆盖旧状态,但不能删除它。

(所以如果 房间主题改变了,那只是覆盖状态,但从房间既不是添加也不是覆盖)。
如果无法找到一个增量,然后您只需从整个状态的“快照”重新开始。

(注意这可能不是服务器处理离开房间的方式,但它可以用于说明目的)

状态组的状态是通过跟随前一个状态组并添加一起所有的增量(以最近的为准)

从状态组到前一个状态组的映射发生在 state_group_edges 中 并且增量存储在state_groups_state

3.1.3 状态表介绍,房间消息和状态列表

接口简介

GET /_matrix/client/r0/rooms/{roomId}/messages

此 API 返回房间的消息和状态事件列表。它使用分页查询参数对房间中的历史进行分页。

注意:此端点支持延迟加载房间成员事件。有关更多信息,请参阅延迟加载房间成员。

	#Path Parameters
		roomId	string    必须的 获取事件的房间。
	#Query Parameters
		from	string    必须的  开始返回事件的令牌。该令牌可以从 /sync API 为每个房间返回的 prev_batch 令牌中获得,也可以从之前对该端点的请求 返回的开始或结束令牌中获得
		to	string    停止返回事件的标记。该令牌可以从同步端点为每个房间返回的 prev_batch 令牌中获得,或者从先前对该端点的请求返回的开始或结束令牌中获得。
		dir	enum   必须  f 或 b  # forwards or     backwards 返回media 顺序
		limit  integer  最多返回多少事件
		filter  string   一个JSON 格式的 房间事件筛选器,为了在返回的事件中进行筛选

返回参数:

		start	string    分页开始的标记。如果 dir=b 这将是 from 提供的令牌。
		end	   string   分页结束标记。如果dir=b 应该再次使用此令牌来请求更早的事件。
		chunk  [RoomEvent]  房间事件列表。 顺序取决于 dir 参数。对于 dir=b 事件将按时间倒序排列,dir=f 为升序排 事件从起点开始
			事件JSON对象中将包括 origin_server_ts ,表示发送此事件时原始家庭服务器上的时间戳(以毫秒为单位)。
		state	[RoomStateEvent]  房间状态事件列表。 如果筛选器 filter中 lazy_load_members 为true,那么chunk将可能包含此事件发送者的成员资格事件。 除非 包括冗余成员(include_redundant_members )是真的,假设这些成员的成员资格没有改变,服务器可能将删除在之前调用此端点时已经发送给客户端的成员资格事件。

			content	object   必须  此对象中的字段将因事件类型而异。与 REST API 交互时,这是 HTTP 正文。
			type	string   必须 事件的类型。这应该是类似于 Java包命名约定的命名空间,例如'com.exa.event.type'
			event_id	string  必须  事件ID,全局唯一
			sender	string   必须  包含发送此事件的用户的完全唯一 ID。
			origin_server_ts	integer  必须  发送此事件时原始家庭服务器上的时间戳(以毫秒为单位)。
			room_id	string    必须  与此事件关联的房间的 ID。尽管在其他任何地方都需要,但不会出现在通过 /sync 到达的事件上。
			prev_content	EventContent  可选 本次活动的上一内容。如果没有以前的内容,则此密钥将丢失。
			state_key	string   必须 	   定义此房间状态的覆盖语义的唯一键。此值通常是零长度字符串。
			   此键的存在使此事件成为状态事件。引用用户 ID以保留@ 开头的状态键,例如房间成员。
			   除了少数事件之外, 当使用给定用户 ID 作为状态键设置的状态事件 时,必须只能由本用户设置。
			unsigned	UnsignedData  可选 包含有关事件的可选额外信息。 与 /sync同步接口返回的类似。

3.1.4 状态解析,消息同步的冲突解决

  • 状态同步与消息同步

    将客户端的状态与服务器上的最新状态同步。客户端在首次登录时使用此 API 获取服务器上状态的初始快照,然后继续调用此 API 以获取状态的增量增量,并接收新消息。

注意:此端点支持延迟加载。有关更多信息,请参阅过滤。仅此端点的 StateFilter 支持延迟加载成员。

启用延迟加载后,服务器必须在用户加入房间或请求房间的完整状态时包含同步用户自己的会员事件,以帮助发现用户的头像和显示名称。

与其他会员一样,用户自己的会员活动有资格被服务器视为多余。

当同步受到限制时,服务器必须为间隙中的事件(在返回时间线的开始和开始之间)返回成员事件,无论它们是否冗余。

这确保了在间隙期间发生的连接/离开和轮廓变化不会丢失。

比如创建房间接口

能见度 枚举 一个公共的知名度表明室将在发布的房间列表中。
一个 私人的知名度将隐藏发布的房间列表房间。

如果不包含此密钥,房间默认为私人可见。注意:这不应与join_rules混淆,后者也使用public一词。其中之一:[“公共”,“私人”]

使用各种配置选项创建一个新房间。

服务器必须在创建新房间时应用正常状态解析规则,包括检查每个事件的功率级别。
它必须按以下顺序应用请求隐含的事件:

	1, m.room.create  是这个房间的第一个事件;
	2, m.room.member 创建者加入房间事件,这是必需的,以便可以发送剩余的事件
	3, m.room.power_levels 事件,授予房间创建者(而非其他成员)发送状态事件的权限, power_level_content_override 重写权限parameter
	4, preset 预设事件状态如下, m.room.join_rules, m.room.history_visibility, m.room.guest_access
	5, 按顺序 初始化 事件列表中的状态,initial_state
	6, 隐含的事件: m.room.name, m.room.topic 事件状态
	7, 邀请事件 invite ,  再次发送 m.room.member事件,设置 membership:invite,

如果是第三方账户 invite_3pid 设置 m.room.third_party_invite 的值 membership:invite,

当服务失去同步状态后,我们最终需要允许,现在遵循以下步骤

  newest -> newish -> oldish -> oldest

或者如下服务的状态冲突:

  A3 -> A2 -> A1     -> oldest
              |(冲突)
        B2 -> B1     -> oldest

凯恩(kahn) 算法,给与服务器终点服务以信用

     A3(newest) -> A2 -> A1  ->  oldest
           B2(newest) -> B1  ->  oldest

第二次

     A2(newest)  -> A1  ->  oldest
            B1(newest)  ->  oldest 

第三次

      A1(newest)  ->  oldest

最后使用matrix细节,如时间戳解决同步关系。

所有服务对应相同的事件都给出相同的结果。
与区块链不同的是:

  A 分离服务器主机是可以的
  B 可以合并历史。

在区块链中这两个问题是难以解决的。 矩阵可以在这样不完整的连接中工作。

3.1.5 那么我们需要压缩什么

为了加快state group id到state的转换,有100个限制。
由服务器设置的跳数限制(也就是说,我们只需要查找最多 100 个状态组)。
它通过每 100 个状态组拍摄另一个“快照”来做到这一点。

然而,正是这些快照占据了突触数据库中的大部分存储空间,
所以我们想找到一种方法来减少它们的数量而不显着增加进行查找所需的最大跃点数。

3.2 特征:分布式实时数据库

实时消息需要分布式的实时数据库,因此矩阵协议支持以下功能:
1 在离线时接收消息
2 支持多种设备登录,同步
3 会话历史支持
4 联合服务器的出现或消失 都不会影响本地服务器
5 坚固的支持网络分离

巨量的服务器相互通信,并且相互分享消息,当有一个服务器发生某个事件时,其他服务器也可以很快知晓并且定义,其数据也可以很快被存储和检索。
这意味着我们确切地需要以下功能:

  1  视频会议和音频房间
  2  协同工作
  3  营造沉浸式环境
  4  端到端,点对点通信。

比如支持元宇宙的虚拟人物的呼出,和对元宇宙人物的呼叫。 包括对 VR 设备的信息的支持。

如WebRTC工作会议。 如何定义两者之间的呼叫,Matrix有一个信号层专门处理此事。(MSC3401 signalling layer over matrix)

语音和视频通话不再通过jitsi 服务,协议本身可以支持,因此不再局限于 对方语音拨号进入jitsi服务,只能于接入的jitsi服务的用户通话。

也就是说,现在拨通之后,可以于不同语音服务器的用户通话,不再局限于一个语音视频服务器。
因此完全支持了全网点对点 或 通过中心代理通信。 我们可以将多个焦点集中在一个房间。
因此解决了用户希望自己控制服务器,并且希望与其他人通信的需求。

CRDT系统可以支持多人同时说话,但是用户可以决定保留哪一个,删除哪一个。 并且不造成冲突和错误。

在矩阵中任何事件都是一个房间。

这些协作工具让我们获得强大的yjs的功能,因此可以接收,删除,编辑文本消息,语音消息,视频会话等等。

小结

示例参考

github.com/loger5/TheBoard
npmjs.com/package/@collabs/collabs
fosdem.org/2022/schedule/event/matrix_filesystem/

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。