Dweb:使用矩阵进行去中心化、实时、互操作的通信

在 Dweb 系列中,我们正在介绍探索将网络去中心化或分布式化后可能性的项目。这些项目与 Mozilla 无关,其中一些项目重新定义了我们对 Web 浏览器的思考方式。它们的共同点是:这些项目都是开源的,可以参与其中,并且它们共享 Mozilla 的使命,即让网络对所有人开放和可访问。

虽然 Scuttlebutt 以人为中心,而 IPFS 以文档为中心,但今天您将了解矩阵,它完全围绕着消息。他们没有发明全新的堆栈,而是借鉴了当今网络的一些熟悉部分——HTTP 作为传输协议,以及 JSON 作为消息格式。这些消息是如何传播的正是它与众不同的地方——一个去中心化服务器系统,从一开始就旨在实现互操作性,并提供一个可扩展性模型来适应不同的用例。请欣赏来自 Ben Parsons 的这篇介绍,他是 Matrix.org 的开发者倡导者。

– Dietrich Ayala

什么是矩阵?

矩阵是一个用于互联网上的互操作去中心化实时通信的开放标准。它提供了一个标准的 HTTP API,用于发布和订阅指定通道中的实时数据,这意味着它可以用于为即时消息、VoIP/WebRTC 信号、物联网通信等任何可以用 JSON 表达并在 HTTP 上实时传输的数据提供支持。今天,矩阵最常见的用途是作为即时消息平台。

  • 矩阵是互操作的,因为它遵循一个开放标准,并且可以与其他平台自由通信。矩阵消息是 JSON 格式的,易于解析。提供桥接器来实现与其他平台的通信。
  • 矩阵是去中心化的——没有中央服务器。要在矩阵上进行通信,您需要将您的客户端连接到一个单一的“主服务器”——该服务器然后与其他主服务器通信。对于您所在的每个房间,您的主服务器将维护该房间历史记录的副本。这意味着,如果有多个主服务器连接到同一个房间,那么没有一个主服务器是该房间的主机或所有者。 任何人都可以自由地托管自己的主服务器,就像他们托管自己的网站或电子邮件服务器一样。

为什么要创建另一个消息平台?

最初的目标是解决 IP 通信碎片化的问题:让用户无需关心对方使用的是什么应用,即可互相发送消息和通话——使其与发送电子邮件一样简单。

未来,我们希望看到矩阵被用作整个网络通用的 HTTP 消息和数据同步系统,通过一个统一、易于理解的接口为物联网和其他应用提供支持。

矩阵提供什么?

矩阵是一个开放标准,它包含一个规范,描述了主服务器、客户端和可以扩展矩阵的应用服务的交互方式。

存在针对各种编程语言的客户端、服务器和 SDK 的参考实现。

架构

您通过客户端连接到矩阵。您的客户端连接到一个单独的服务器——这就是您的主服务器。您的主服务器存储和提供已连接用户的历史记录和帐户信息,以及该用户加入的房间的历史记录。要注册,您可以在 hello-matrix.net 上找到公共主服务器列表,或者如果您使用 Riot 作为您的客户端,则客户端会建议一个默认位置。

主服务器将消息历史记录与其他主服务器同步。这样,您的主服务器就负责存储房间状态并提供消息历史记录。

让我们看一个关于它如何工作的示例。主服务器和客户端按照图 1 中的示意图连接。

图 1. 连接了客户端的主服务器
Figure 1. Homeservers with clients

图 2.
Figure 2. Private vs shared homeservers

如果我们加入一个主服务器(图 3),这意味着我们将我们的客户端连接到该主服务器上的一个帐户。

图 3.
Figure 3. Joining a homeserver

现在我们发送一条消息。此消息被发送到我们客户端指定的房间,并由主服务器分配一个事件 ID。

图 4.
Figure 4. Sending a message

我们的主服务器将消息事件发送到每个拥有该房间中属于其用户的帐户的主服务器。它还会将该事件发送到该房间中的所有本地客户端。(图 5)

图 5.
Figure 5. Homeserver message propagation

最后,远程主服务器将消息事件发送到它们的客户端,这些客户端恰好在相应的房间中。

图 6.
Figure 6. Message delivery

使用示例——简单的聊天机器人

让我们使用 matrix-js-sdk 创建一个小型聊天机器人,它会在房间里监听并以回声回复。

创建一个新目录,安装 matrix-js-sdk 并开始吧。

mkdir my-bot
cd my-bot
npm install matrix-js-sdk
touch index.js

现在在您的编辑器中打开 index.js。首先,我们创建一个 client 实例,它将我们的客户端连接到我们的主服务器。

var sdk = require('matrix-js-sdk');

const client = sdk.createClient({
  baseUrl: "https://matrix.org",
  accessToken: "....MDAxM2lkZW50aWZpZXIga2V5CjAwMTBjaWQgZ2Vu....",
  userId: "@USERID:matrix.org"
});

baseUrl 参数应与尝试连接的用户的主服务器匹配。

访问令牌与帐户相关联,并提供对该用户可用的所有房间的完整读写权限。您可以在 Riot 中获取访问令牌,方法是转到设置页面。

如果服务器支持,也可以通过编程方式获取令牌。为此,创建一个没有身份验证参数的新客户端,然后使用 "m.login.password" 调用 client.login()

const passwordClient = sdk.createClient("https://matrix.org");
passwordClient.login("m.login.password", {"user": "@USERID:matrix.org", "password": "hunter2"}).then((response) => {
  console.log(response.access_token);
});

有了此访问令牌,您现在可以像上一个代码片段中那样创建新的客户端。建议您保存访问令牌以便重复使用。

接下来,我们启动客户端并执行第一次同步,以从主服务器获取最新状态。

client.startClient({});
client.once('sync', function(state, prevState, res) {
  console.log(state); // state will be 'PREPARED' when the client is ready to use
});

我们监听我们订阅的房间的事件。

client.on("Room.timeline", function(event, room, toStartOfTimeline) {
  handleEvent(event);
});

最后,我们通过以“!”开头的消息进行回声来响应事件。

function handleEvent(event) {
  // we know we only want to respond to messages
  if (event.getType() !== "m.room.message") {
    return;
  }

  // we are only interested in messages which start with "!"
  if (event.getContent().body[0] === '!') {
    // create an object with everything after the "!"
    var content = {
      "body": event.getContent().body.substring(1),
      "msgtype": "m.notice"
    };
    // send the message back to the room it came from
    client.sendEvent(event.getRoomId(), "m.room.message", content, "", (err, res) => {
      console.log(err);
    });
  }
}

了解更多信息

了解矩阵的最佳场所是在矩阵本身!参与矩阵的最快方法是使用 Riot,这是一个流行的基于 Web 的客户端。前往 <https://riot.im/app>,注册一个帐户并加入 #matrix:matrix.org 房间,向大家介绍自己。

matrix.org 提供了许多资源,包括 常见问题解答指南 部分。

最后,要直接开始编写代码,请查看 矩阵规范,或参与众多 开源项目

关于 Ben Parsons

Ben 是 matrix.org 的开发者倡导者。

Ben Parsons 的更多文章……


9 条评论

  1. Pluto

    我想被下载到矩阵中!

    2018 年 10 月 17 日 下午 4:02

    1. Ben Parsons

      那么您应该去 https://riot.im/app/ 注册!

      2018 年 10 月 19 日 上午 2:15

  2. amit

    是否有端到端加密的规范?

    2018 年 10 月 18 日 上午 10:39

    1. Ben Parsons

      您好 Amit,

      您可以在此处找到有关 E2E(包括规范链接)的许多信息:https://matrix.org/blog/2016/11/21/matrixs-olm-end-to-end-encryption-security-assessment-released-and-implemented-cross-platform-on-riot-at-last/

      有关规范的客户端实现信息,文档位于此处:https://matrix.org/docs/guides/e2e_implementation.html,但请注意,目前正在进行主要的文档工作。您可以在此处了解此工作的最新进展:https://github.com/matrix-org/matrix.org/pull/201

      谢谢,
      Ben

      2018 年 10 月 18 日 下午 12:12

  3. frustigor

    不错的技术!
    但是,如您所示的 SDK,如何创建公共主服务器?

    2018 年 10 月 18 日 下午 7:29

    1. Ben Parsons

      您好 frustigor,

      今天最受欢迎的矩阵主服务器是 Synapse。请查看 https://github.com/matrix-org/synapse/ 上的自述文件,其中包含非常详细的安装说明。还有 Docker 镜像可用,或者如果您更喜欢 Ansible,请查看社区创建的这些剧本:https://github.com/spantaleev/matrix-docker-ansible-deploy/

      谢谢

      2018 年 10 月 19 日 上午 2:12

  4. geek42

    听起来像 XMPP,只是用 JSON 替换了 XML :D

    2018 年 10 月 18 日 下午 7:49

    1. Ben Parsons

      矩阵在许多方面与 XMPP 相似——尤其是在启用即时消息方面!但是,在其他方面,它们的底层技术存在着巨大的差异——当然比 XML 与 JSON 的差异要大得多!

      有关更多信息,请查看我们关于此主题的常见问题解答:https://matrix.org/docs/guides/faq#what-is-the-difference-between-matrix-and-xmpp%3F

      2018 年 10 月 19 日 上午 2:18

  5. Ranjith Raj

    我们能否拥有一个 Mozilla 托管的矩阵服务器?(我们可以尝试将它们与 Mozilla 的 IRC 频道桥接。)

    在 Mozilla 的矩阵服务器上创建所有群组矩阵房间将很有帮助。

    2018 年 10 月 19 日 下午 8:33

本文的评论已关闭。