使用MongoDB和Node.js构建实时Web应用程序

18

我一直在思考如何使用nodejs / socket.io / mongodb创建实时Web应用程序。这个想法与Google文档非常相似,页面上编辑的对象会被发送到所有客户端浏览器并重新呈现。

最好的方法是什么?根据我所了解的,我能够想到3种方法:

1)使用mongodb oplogs

向mongodb集合添加“监听器”,每当对集合进行更改时重新呈现页面的部分内容(缺点:速度较慢?)

2)使用本地json

将mongodb数据检索到json文件中,使用fs进行编辑,在完成后保存到mongodb并删除json(缺点:在数据库和实际应用程序之间有额外的层次感,不太方便)

3)仅使用socket.io

重新呈现而不存储,仅在所有更改完成后保存(缺点:文件可能无法在所有浏览器上正确呈现)

是否有更好的方法来实现这一目标?(Google Docs到底是如何工作的?)真的很感谢任何人可以提供的帮助!

6个回答

23

去年我们开发了一款实时应用程序,基本上是为作者提供的一个工具,让他们可以在同一页上添加/删除/编辑元素(文本、图像、视频等)。

我们使用的技术包括:

  • Node.js,并配合 Hapi.js 框架(基于 express)
  • Socket.io
  • 不是 MongoDB,而是使用了很棒的RethinkDB,该数据库自带实时功能,基本上使用监听器告诉你何时有变化发生。(在我们看来,mongoDB 不怎么好用,我们过去曾使用过它,但感觉“再也不用了”,但这只是我们的想法)
  • React/Redux 只更新已更改的 DOM 元素,使用 Angular 的双向数据绑定会导致重新渲染所有元素,因此在我们看来不太适合,因为多个用户可能同时修改同一页,重新渲染所有元素会导致失去焦点。

老实说,它运行得非常快速。


这真的很类似于我想要制作的东西!以前从未听说过Rethink,但是Rethink和React听起来就是我需要的。除了在大型团队中保持一致性之外,Hapi是否具有比Express更特殊的优势? - Poh Zi How
1
我喜欢hapi,因为它具有模块化的特点。它基本上是以更模块化的方式构建的Express框架。你可以使用任何一个,这并不重要。这里有一个非常好的关于两者之间主要区别的解释:https://dev59.com/3V0a5IYBdhLWcg3wVHMm - Vadorequest
刚看到这篇文章,我很想尝试RethinkDB。不幸的是,最后一次git更新已经快一年了。这让人怀疑它是否还在继续开发。 - Niklas
@Niklas https://www.rethinkdb.com/blog/2.3.6-release/ 他们曾经遇到过一些困难,因为公司没有赚到足够的钱,但是他们处理得非常好,现在它仍然是开源的并且得到了维护。你可以通过链接了解更多信息。 - Vadorequest
如果我想将Redis加入到这个混合中,它有什么用处呢?因为当涉及实时Web应用程序时,我看到很多人都在谈论它!! - Siempay
如果您需要获取外部数据,例如连接到数据库,则可以使用Redis。如果在数据库前面使用Redis,则可能会更快(Redis比数据库更快,这基本上就是它的优点),并避免过载数据库连接。 - Vadorequest

3
这很容易解决,无需复杂操作并将文档保存到数据库中。您只需要保存文档位置即可。Node有一些非常棒的功能专门为此类应用程序而设计。我建议您查看以下主题:
- 事件发射器 - 流
Node文件系统具有可用于构建文档的类: 你可以使用socket.io将这些事件连接到你的客户端应用程序。

1
这个解决方案可以工作,但是Node的fs模块并不是实现目标最有效的方式之一。如果你正在开发演示产品或POC,它肯定会节省很多时间。 - Bala Abhinav

2
我建议采用第一项和第三项,不过有些差别。 1. 监听mongoDB opLog的第一个选项很好,但当你的应用程序在处理数百万个事务时,它会变得非常耗费资源。MeteorJS库已经实现了这个功能,你可以使用它们,因为它们比编写我们自己的服务更加成熟和稳定。 3. 第三个选项是使用socket.io。如果你正在使用支持原生changefeeds的rethinkDB,你可以使用socket.io来发布更改并写入数据库。原生changefeeds意味着每次对你要实时监视的表/集合进行写入操作时,它都会回调旧数据和新数据,你可以使用socket.io将其发布给所有客户端。 另一种更健壮的解决方案是使用rabbitMQ,就像Paul上面提到的那样。

1
如果我要做这个,我可能会使用混合方式。Redis或rabbitmq来管理socket.io连接列表,以便尽快获得发布和订阅行为,并使用定时作业定期刷新文档的写入到mongodb中,以实现长期持久性,尽管如果您愿意,您可以将所有文档留在Redis中。

1
"构建协同文档编辑应用程序"实际上是《精通Node.js》一书中的一章。他们使用:

另外,MongoDB最近发布了一份关于使用Apache Kafka进行数据流处理以实现实时能力的白皮书:https://webassets.mongodb.com/kafka_and_mongodb.pdf


-2

我认为使用socketIO同步数据是最好的方式...... 通过emit将数据发送到mongo。 使用socket监听数据库中的更改,并使用这些更改重新渲染页面。

您还可以访问nodejs实时mongodb!了解如何使用regina自动同步数据。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接