22

我有一个很好的老式 LAMP webapp。一周前,我需要为其添加一个推送通知机制。
因此,我所做的是在服务器上添加 node.js+socket.io 并使用 node.js 每 10 秒轮询 MySQL 数据库以检查是否有新项目:如果有,我会将它们发送到客户端( s) 使用 socket.io。
我对结果非常满意,即使这不是一个适当的实时通知(因为最多有 10 秒的延迟)。

现在,我即将构建一个新的 web 应用程序,它也需要推送通知。我想知道是采用与第一种方法相同的方法(我相信它更稳定和成熟)还是完全采用 Node.js,而不使用 PHP 和 Apache。至于数据库,我已经决定去MongoDB了。

最后,我的问题是:如果我选择 Node.js+Socket.io+MongoDB,我会得到一个真正 接近实时的webapp 吗?我的意思是,一旦将新记录插入 MongoDB,是否会触发某种事件,我可以通过 node.js 捕获,对其进行检查,如果相关,将通知发送给客户端?还是会像我的第一个 LAMP webapp 一样,在 db 服务器端和延迟上进行某种轮询?

一个相关的问题:你能在 MySQL 上构建一个实时 webapp,而不像我第一个应用程序那样做任何轮询吗?还是您需要 MongoDB(或 Redis)?

我希望这个问题不会太傻 - 抱歉,我只是从 Node.js 和 co 开始。

谢谢。

4

6 回答 6

16

我理解你的问题,因为我也从php /apache/mysql切换到node.js。

  • 一般 node.js 是稳定的,模块和你的脚本是错误的主要原因

  • 实时与数据库无关,它是关于客户端和服务器的,您可以在请求中查询任意数量的数据并将其推送到另一个客户端。

  • 选择 node.js 是非常明智的,但它更难实现。

  • 当您将新记录插入数据库时​​,事件就是请求本身,您将与数据库查询一起进行推送事件,例如:

    // Please note this is not real code, just an example of the idea
    app.get('/query', function(request, response){
        // Query your database
        db.query('SELECT * FROM users', function(rows){
    
             // Push notification to dan
             socket.emit('database_query_executed', 'to_dan', rows); 
    
             // End request
             response.end('success'); 
    
        })   
    })
    
  • 当然你可以使用MySQL!正如我所说,您想要的任何数据库都与数据库无关,因为数据库处于流程的中间,并且完全是可选的。

  • 如果您想使用node.js进行推送通知,使用php/apache进行mysql,那么您需要为每个服务器创建 2 个请求,例如:

    // this is javascript
    ajax('http://node.yoursite.com/push', node_options)
    ajax('http://php.yoursite.com/mysql_query', php_options)
    

    或者如果你只想要一个请求,或者你想使用一个表单,你可以调用你的php,在 php 中你可以从 php 创建一个对 node.js 的 http 或 net 请求,比如:

    // this is php
    new HttpRequest('http://node.youtsite.com/push', HttpRequest::METH_GET);
    
于 2012-10-21T19:17:46.357 回答
7

使用:

  • 一个常规的 MongoDB Collection 作为Store
  • 以可尾游标为队列的 MongoDB Capped 集合
  • 具有 Socket.IO 的 Node 工作人员将 Queue 作为Worker观察,
  • 一个节点服务器,用 Socket.IO 客户端为页面提供服务,并作为服务器接收 POST 数据(或者其他数据被添加

它是这样的:

  1. 新数据被发送到服务器,
  2. Server 将数据放入 Store,
  3. 服务器将数据的 ObjectID 添加到队列中,
  4. Queue 会将新到达的 ObjectID 发送到 Worker 上打开的 Tailable Cursor,
  5. Worker 去从 Store 中获取 ObjectID 中的实际数据,
  6. Worker 通过套接字发出数据,
  7. 客户端从套接字接收数据。

这是从最初添加数据一直到客户端接收的“推送” - 没有轮询,因此您可以获得实时的每一步处理时间。

于 2012-10-25T21:52:03.707 回答
2

回复:MongoDB 中的触发器 - 请参阅此答案:https ://stackoverflow.com/a/12405093/1651408

MySQL 中有更方便的触发器,但是从它们调用 Node.js 需要一些使用 MySQL UDF(用户定义函数)的工作,例如通过 Unix 套接字推送数据。请注意,仅当其他应用程序(除了您的 Node.js 进程)正在更新数据库时才需要这样做,并且在这种情况下确保选择 InnoDB 作为存储(行级与表级锁定)。

可以看出您的技术选择没有什么大问题sockets.io,即使不支持客户端 Web 套接字,您也会(我希望优雅地)退回到轮询。

最后,你的问题一点也不傻,因为推送技术绝对优于大量的轮询请求——它的扩展性更好。编辑:但是,不会将这两种技术描述为实时的

另一个编辑:对于这种非常知名且成功的设置,请阅读:http ://blog.fogcreek.com/the-trello-tech-stack/

于 2012-10-21T19:22:39.413 回答
2

你发现Chole了吗?它与您的 Web 服务器分开工作,并通过使用 HTTP POST 与其交互。这样,您就可以按照您想要的任何方式编写您的网络应用程序。

于 2012-10-27T03:54:43.330 回答
1

实际上使用像Socket.IO这样的推送技术可以帮助您使用

有效地利用服务器的资源,还可以帮助您将旧浏览器利用到现代浏览器进行 websocket 或类似 websocket 的连接。

10 秒轮询是一个昂贵的 HTTP 请求,尤其是当有很多用户在场时。

与轮询技术不同,推送技术相对便宜。用户的客户端正在打开一个专用的套接字(即 websocket)来监听服务器的推送通知。

通常,您的客户端 JavaScript 在收到推送通知时会执行一些操作。

使用具有不同端口(80 除外)的 LAMP 堆栈和 Socket.IO 将足以满足您的需求。

但是使用 Node.js + MongoDB + Socket.IO 实际上可以帮助您更有效地管理服务器资源。

因为这三个具有非阻塞性质。

如果您正确理解非阻塞概念并正确实施您的应用程序,

您相同的应用程序,具有相同功能但具有不同语言和不同数据库的应用程序,将能够处理比一般 LAMP 堆栈更多的请求。


在此处输入图像描述

上图是比较 Non-blocking 与 Thread 方式处理并发的著名图表

Apache(线程)与 Nginx(非阻塞)


MySQL 是一个很棒的数据库。我相信你不需要join实时transactions通知。

除非您自己实现类似的功能,否则 MongoDB 没有这两个功能。

由于没有这两个特性以及它自己的一些特性,MongoDB 可以比传统的 SQL 数据库更快地存储和获取数据。

从 MySQL 切换到 MongoDB 将减少插入和获取数据的时间。

于 2012-10-25T01:28:49.437 回答
0

使用 JS 你可以打开一个到你的服务器的套接字(不是旧的浏览器),服务器将有一个 ah-hoc 程序(在一个 ad-hoc 端口上,所以你需要打开门并在你的服务器上运行程序的权限),它将从客户端发送数据(几乎)实时,并且没有 HTTP 的协议开销。旧浏览器将回退到轮询机制。

我看不到其他方法可以做到这一点(可能已经有“coocked”框架可以做到这一点)

于 2012-10-19T16:12:11.847 回答