在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
发布和订阅发布(Publication)和订阅(Subscription)是 Meteor 的最基本最重要的概念之一,但是如果你是刚刚开始接触 Meteor 的话,也是有些难度的。 这已经导致不少误解,比如认为 Meteor 是不安全的,或者说 Meteor 应用无法处理大量数据等等。 人们起初会感觉这些概念很迷惑很大程度上是因为 Meteor 像变魔法一样替你做了很多事儿。尽管这些魔法最终看起来很有效,但是它们掩盖了后台真正做的工作(好像魔术一样)。所以让我们剥去魔法的外衣来看看究竟发生了什么。 过去的日子首先,让我们回顾一下2011年之前,当 Meteor 还没有诞生的时候的老日子。比如说我们要建立一个简单的 Rails app。当用户来我们的站点,客户端(举例说浏览器)向我们的服务器端的 app 发送请求。 App 的第一个任务就是搞清楚这个客户请求什么数据。这个可能是搜索结果的第12页、玛丽的用户信息、鲍勃的最新20条微博,等等等等。 你可以想想成为一个书店的伙计在书架之间帮你寻找你要的书。 当正确的数据被找到,这个 App 的下一个任务就是把数据转换成好看的,人类可读的 HTML 格式(对于 API 而言是 JSON 串)。 用书店来举例,那就相当于是把你刚买的书包好,然后装入一个漂亮的袋子。这就是著名的 MVC(模型-视图-控制器)模式中的视图部分。 最终,App 把 HTML 代码送到客户端。这个 App 的任务也就交差了。它可以去买瓶啤酒然后等着下一个请求。 Meteor 的方式让我们看看 Meteor 相对之下是多么的特别。正如我们看到的,Meteor 的关键性创新在于 Rails 程序只跑在服务器上,而一个 Meteor App 还包括在客户端(浏览器)上运行的客户端组件。 推送数据库子集到客户端 这就相当于书店的伙计不仅仅在书店里帮你找书,还跟你回家,每天晚上读给你听(这听起来怪怪的)。 这种架构可以让 Meteor 做更多很酷的事情,其中一件主要的就是 Metoer 变得数据库无处不在。简单说,Meteor 把你的数据拿出一部分子集复制到客户端。 这样后两个主要结果:第一,服务器不再发送 HTML 代码到客户端,而是发送真实的原始数据,让客户端决定如何处理线传数据。第二,你可以不必等待服务器传回数据,而是立即访问甚至修改数据(延迟补偿 latency compensation)。 发布一个 App 的数据库可能用上万条数据,其中一些还可能是私用和保密敏感数据。显而易见我们不能简单地把数据库镜像到客户端去,无论是安全原因还是扩展性原因。 所以我们需要告诉 Meteor 那些数据子集是需要送到客户端,我们将用发布功能来做这个事儿。 让我们来回到 Microscope。这里是我们 App 数据库中的所有帖子: 数据库中的所有帖子数据 尽管实际上不存在但是我们还是假设我们的帖子中有几条因为言语不当被打了特殊标记的。我们需要把他们留在数据库中但是不希望让用户看到(发送去客户端)。 我们第一个任务就是告诉 Meteor 那些数据我们要发送去客户端。我们告诉 Meteor 我们只发布没有打标记的帖子。 排除做过标记的帖子 这里是对应的代码,在服务器端代码中。
这就保证客户端无论如何也无法看到打了标记的帖子了。这就是 Meteor App 如何做到安全性的:保证只发布你让这个当前用户看到的数据。 DDP基本上我们可以把发布/订阅模式想象成为一个漏斗,从服务器端(数据源)过滤数据传送到客户端(目标)。 这个漏斗的专属协议叫做 DDP(分布式数据协议 Distributed Data Protocol 的缩写)。如果想了解 DDP 的更多细节,可以通过看 Matt DeBergalis(Meteor 创始人之一)在 Real-time 大会上的讲演视频,或者来自 Chris Mather 的这个截屏视频,来学习关于这个概念更多的细节。 订阅就算是我们想把打了标记的帖子也发送给客户端,我们也不能把成千上万的帖子一股脑都发出去。我们需要一个机制让客户端来确定那些子集是他们在某个特别时候特别需要的,这就是订阅这个功能的用途。 通过 MiniMongo,客户端 MongoDB 的应用,你订阅的数据会被镜像到客户端。 举个例子,让我们现在浏览一下 Bob Smith 的个人页面,这里只会显示他的帖子。 订阅 Bob 的帖子镜像到客户端 首先,我们给发布功能加一个参数:
然后我们在客户端订阅这个发布时定义同一个参数。
这就是我们让 Meteor 程序在客户端能够具有可伸缩性:不去订阅全部数据,而是指选择你现在需要的数据去订阅。这样的话,你就可以避免消耗大量的客户端内存,无论服务器端的总数据量有多大。 查找现在 Bob 的帖子恰巧涵盖了多个类别(比如:“JavaScript”、“Ruby”和“Python”)。也许我们仍然需要把 Bob 的所有帖子都装入内存,但是我们现在只想显示属于“JavaScript”类别的帖子。这就是“查找”的用途。 在客户端选择一个数据子集 正如我们在服务器上做的一样,我们用了
现在我们应该明白订阅和发布机制了,让我们在深入了解一些常见的应用模式。 自动发布如果你从头开始建立一个 Meteor 项目(比如,使用
自动发布 那么这究竟是如何工作的呢?假设在服务器端我们有一个集合叫做 因此,如果你使用自动发布,你就不需要考虑发布。数据一致,而且事情变得十分简单。当然,这样的话会有一个明显的问题,就是你的所有数据都被缓存到所有用户的电脑中。 基于这个原因,自动发布只在你起步阶段且还未考虑发布之前时使用。 发布全部集合一旦你删除掉
发布所有集合 我们还是发布了所有集合,但是至少我们现在可以自己控制哪个集合我们发布哪个不发布。比如现在这个例子,我们发布了 发布部分集合下一步我们要做的是发布集合中的_部分_记录。比如我们只发布来自于某个作者的帖子:
发布集合的一部分 幕后真相如果你已经阅读了 Meteor 发布文档,你可能被诸如 原因在于 Meteor 提供了十分重要的简化: 当 Meteor 看到 下面就是
所以在上述的例子中,我们可以保证用户只会在客户端缓存中得到他们感兴趣的帖子(在这里例子中是 Tom 发的帖子)。 发布部分字段我们已经看到如何发布部分帖子,但是我们还需要再精简!让我们看看如何只发布指定的部分字段。 如同以前我们使用
发布部分字段 实际上,我们可以同时使用上述两种技术,只发布作者是 Tom 的帖子,并且隐藏 date 日期字段:
总结我们已经从发布所有集合的所有文档的所有字段(通过 这已经覆盖了 Meteor 的发布的基本内容,而且这些基本技巧已经足够涵盖大部分的用例了。 有时,你需要进一步来组合、连接或融合发布。我们在以后的章节中讲到这些内容! |
请发表评论