8

我实际上已经玩了一点 Meteor,但我意识到我仍然缺乏对这个主题的一些(或很多!)理解。

例如,这里有一个使用 node.js/express/socket.io 进行简单实时聊天的教程:http: //net.tutsplus.com/tutorials/javascript-ajax/real-time-chat-with -nodejs-socket-io-and-expressjs/

在上面的示例中,通过 socket.io,网络服务器接收一些数据并将其传递给所有连接的客户端——所有这些都没有任何数据库访问。

使用 Meteor,在我见过的所有示例中,客户端通过写入 mongodb 来更新,然后更新所有客户端。但是如果我不需要将数据写入数据库怎么办?将数据传递给所有客户端似乎是一个昂贵的步骤。

我确定我在这里遗漏了一些东西。Meteor 更新所有客户端的方式是什么(例如,使用简单的聊天应用程序),但不需要先写入数据库的费用?

谢谢!

4

4 回答 4

10

目前还没有官方的方法可以在不将数据写入集合的情况下将数据发送给客户。它在流星中有点小技巧,因为当多个流星一起使用时,当没有地方写入时向多个客户端发送数据的步骤来自于多个流星。即从一个流星发送的项目不会到达另一个订阅的客户。

有一个使用 Meteor Streams ( http://meteorhacks.com/introducing-meteor-streams.html ) 的临时解决方案,它可以让你做你想做的事,而无需同时写入数据库。

如果您想了解一些技术细节,在流星谈话( https://groups.google.com/forum/#!topic/meteor-talk/Ze9U9lEozzE )上也有相当广泛的讨论。当链接器分支合并到主服务器时,这实际上将成为可能,对于单个服务器

这是拥有“虚拟收藏”的一些方法,它并不完美,但它可以做到,直到 Meteor 有一种更完善的方式来完成它。

Meteor.publish("virtual_collection", function() {
    this.added("virtual_coll", "some_id_of_doc", {key: "value"});

    //When done
    this.ready()
});

然后在客户端订阅这个:

var Virt_Collection = new Meteor.Collection("virtual_coll");
Meteor.subscribe("virtual_collection");

然后你可以在订阅完成后运行它:

Virt_Collection.findOne();
=> { _id: "some_id_of_doc", key: "value"}

这有点混乱,但您也可以使用它来更新或删除集合。至少这种方式虽然你不会使用任何插件或包。

有关更多详细信息和视频示例,请参阅:https ://www.eventedmind.com/posts/meteor-how-to-publish-to-a-client-only-collection。

于 2013-07-23T13:02:40.503 回答
6

服务器上的发布功能将数据发送到客户端。它有一些从数据库发布查询结果的便捷快捷方式,但您不必使用这些快捷方式。发布函数具有 this.added()、this.removed() 和 this.changed(),允许您发布您选择的任何内容。然后客户端订阅并接收发布的数据。

例如:

if ( Meteor.isClient ){
  var someMessages = new Meteor.Collection( "messages" );  //messages is name of collection on client side
  Meteor.subscribe ( "messagesSub" );  //messagesSub tells the server which publish function to request data from

  Deps.autorun( function(){
    var message = someMessages.findOne({});
    if ( message )  console.log( message.m ); // prints This is not from a database
  });
}

if (Meteor.isServer ) {
  Meteor.publish( "messagesSub", function(){
    var self = this;
    self.added ( "messages", "madeUpId1", { m: "This is not from a database"} ); //messages is the collection that will be published to
    self.ready();
  });
}

流星文档中有一个例子在这里解释,另一个例子在这里。我还有一个示例,它在客户端之间共享数据,而无需使用数据库,只是为了自学发布和订阅的工作原理。除了基本的流星,什么都没用。

于 2013-07-24T11:17:35.217 回答
3

可以使用 Meteor 的 livedata 包(他们的 DDP 实现)而不需要服务器上的数据库。这是由 Avital Oliver 演示的,下面我将指出相关部分。

魔法发生在这里:

if (Meteor.isServer) {
    TransientNotes = new Meteor.Collection("transientNotes", {connection: null});
    Meteor.publish("transientNotes", function () {
        return TransientNotes.find();
    });
}

if (Meteor.isClient) {
    TransientNotes = new Meteor.Collection("transientNotes");
    Meteor.subscribe("transientNotes");
}

设置connection: null指定无连接(请参阅 Meteor 文档)。


Akshat 建议使用流。由于缺乏声誉,我无法回复他的评论,所以我将其放在这里。他链接到的包不再被积极维护(参见作者的推文)。我建议使用 yuukan:streamy(在 Atmosphere 上查找)包,或者使用 Meteor 本身使用的底层 SockJS 库——您可以通过查看 Meteor 代码并查看 Meteor.server.Stream_server 来了解如何执行此操作,以及使用 Meteor.connection._stream,这就是 Streamy 包的作用。

我测试了 Streamy 聊天示例的实现,发现性能差异可以忽略不计,但这只是初步测试。使用第一种方法,您可以获得 minimongo 实现(例如查找)和 Meteor 反应性的好处。Streamy可以实现反应性,但可以通过使用 ReactiveVar 之类的方法来实现。

于 2015-03-10T11:27:46.567 回答
1

有一种方法!至少理论上 Meteor 用来在客户端和服务器之间进行同步的协议称为 DDP。规格在这里

尽管这里这里有一些人们实现自己的 DDP 客户端的示例,但恐怕还没有看到 DDP 服务器实现的示例。但我认为该协议很简单,并且猜想它不会那么难实现。

于 2013-07-24T19:32:01.307 回答