使用 Symfony 实现长轮询 API
我正在尝试实现一个在 Symfony 框架中使用长轮询概念的 API。
假设我有一个只能增长的表“提要”(假设用户可以从其他界面插入他们的提要)。 我想创建一个客户端实时更新的页面。想法是这样的:
- 客户端发送一个带有上次修改时间戳的ajax请求(第一次发送0)
- 服务器将客户端的时间戳与时间戳进行比较,以检索时间戳大于用户发送的所有消息
- 如果有更新的消息,则返回立即将它们发送给客户端,并带有最新的时间戳 另一方面,如果没有新消息,则进入 2 分钟的忙等待循环,每 1-3 秒(随机)检查是否有新消息。
- 当客户端收到服务器应答时,浏览器更新视图并立即发送新的ajax请求。
换句话说,服务器不是每 x 秒发送一次 AJAX 调用,而是保留请求,直到它为我们提供新信息。
凭借 Symfony 的良好经验,我尝试实现此 api 的一个简单演示,而且效果很好。我遇到了会话阻塞问题(ajax 调用被保留,因此无法访问服务器),因此我只是将以下内容添加到操作中:(
public function executeIndex(sfWebRequest $request)
{
session_write_close();
:
:
另请参阅 此链接)
然后我测试对 API 的大量访问。 100 个用户工作正常,1000 个用户一切都崩溃。 我意识到我有两个问题:
- 对于每次访问,都会打开一个新的数据库连接
- 对于每次访问,服务器都会执行一个新进程
对于第一个问题,我尝试将 persistent: true
放入我的database.yml Doctrine中连接器。当我监控服务器连接时,我发现每次访问 API 仍然会打开一个新连接。所以基本上我仍然被同样的两个问题所困扰。
有谁对这个问题有任何想法或经验吗?或者也许我应该放弃用 Symfony 实现我的 api 的想法?
I am trying to implement an API which uses the long-polling concept in Symfony framework.
Let's say that I have a table 'feeds' which can only grow (assume that users can insert thier feed from other interface).
I want to create a client-side real-time updated page. The idea is the following:
- Client send an ajax request with timestamp of last modification (first time sends 0)
- Server compares timestamp of client to timestamp, to retrieve all messages with bigger timestamp than the one sent by user
- If there are newer messages, return them immediately to the client, with the timestamp of the latest one
On other hand, if there are no new messages, enter into a 2 minutes busy-wait loop, checking every 1-3 seconds (randomly) whether there are new messages. - When client receive servers answer, browser updates view and immediately sends a new ajax request.
In other words, instead of send an AJAX call every x seconds, the server holds the request till it has new information for us.
Having good experience with Symfony I tried to implement a simple demo of this api, and it works great. I had a problem of session blocking (the ajax call is held so access to the server is not possible), so I simply added the following to the action:
public function executeIndex(sfWebRequest $request)
{
session_write_close();
:
:
(see also this link)
Then I testes massive access to the API. 100 users works fine, 1000 everything crashes.
I realized that I have two problems:
- For each access a new DB connection is opened
- For each access the server executes a new process
For the first problem I tried to put persistent: true
In my database.yml Doctrine connetor. When I monitored the server connections I saw that still each access to the API opens a new connection. So basically I am still blocked with the same two problems.
Does anyone have any idea or experience with this issue?? Or maybe I should give-up the idea of implementing my api with Symfony??
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为为此使用 symfony 是错误的方法。使用套接字会容易得多。
例如,查看 nodejs 或 ape-project (comet)
它们都能够处理比 apache、lighttpd 或 nginx 更多的当前用户...
I think using symfony for this, is the wrong approach. Using Sockets would be much easier.
For example have a look at nodejs or ape-project (comet)
they both are able to handle much more current users than apache, lighttpd or nginx...
Apache为每个用户创建不同的线程,并且每个线程都有一个单独的数据库连接。这就是数据库连接高的原因
Apache creating different threads for each user and each thread have a separate database connection. that's why the db connection are high