【问题标题】:Is this the proper method to Long Polling(Comet programming)这是长轮询(彗星编程)的正确方法吗
【发布时间】:2023-04-06 14:13:01
【问题描述】:

首先,我要感谢你们所有对新程序员如此有帮助的伟大人物。

我有一个关于长轮询的问题。我研究了一些关于彗星编程的长轮询技术的文章。该方法对我来说似乎很难,因为它有时还需要在服务器端安装一些脚本。

现在我找到了一个关于长轮询的例子。它工作得很好,但我不确定它是否是正确的方法。示例脚本是关于一个类似聊天的应用程序。这个 php 脚本的工作原理如下:

  1. php 脚本不断检查 data.txt 文件,直到更改为止。
  2. data.txt一更改,网页上就会输出新的文本。

这是 php 脚本:

<?php
$filename  = dirname(__FILE__).'/data.txt';

// store new message in the file
$msg = isset($_GET['msg']) ? $_GET['msg'] : '';
if ($msg != '')
{
    file_put_contents($filename,$msg);
    die();
}

// infinite loop until the data file is not modified
$lastmodif    = isset($_GET['timestamp']) ? $_GET['timestamp'] : 0;
$currentmodif = filemtime($filename);
while ($currentmodif <= $lastmodif) // check if the data file has been modified
{
    usleep(500000); // sleep 500ms to unload the CPU
    clearstatcache();
    $currentmodif = filemtime($filename);
}

// return a json array
$response = array();
$response['msg']       = file_get_contents($filename);
$response['timestamp'] = $currentmodif;
echo json_encode($response);
flush();
?>

为了简单起见,我没有包含网页代码。该网页只有一个 div,每当更改时都会显示 data.txt 的文本。

我的问题的要点是:

  • 这种循环方法是长轮询服务器的正确方法吗?
  • 另外,当服务器正在执行sleep(); 时,其他并发请求会怎样?
  • 是否有任何技术可以减少由于长轮询的连续脚本造成的服务器负载
  • 如果启动此长轮询请求的客户端断开连接,我们如何知道并相应地停止该断开连接客户端的脚本

请指导我解决这个问题...谢谢

【问题讨论】:

    标签: php javascript ajax comet long-polling


    【解决方案1】:

    是的,这是一个想法。您应该记住,该脚本不会结束,并且将为每个用户生成一个 PHP 实例。我在 v8cgi 服务器端使用 longpoll 逻辑。客户端启动 XMLHttp 请求 (XHR) 后,服务器开始检查新输入的间隔。我添加了一个计时器服务器端,每 5 分钟发送一次响应,之后客户端(如果未断开连接)重新发送 XHR 并重复该过程。

    因此,服务器端机制的每个实例最多运行 5 分钟,因为如果客户端断开连接,服务器在 5 分钟后发送的响应不会跟随新的 XHR。

    流程如下:

    • 客户端发送 XHR
    • 服务器衍生进程定期检查更新
    • 如果必须发送一些更新:服务器发送响应
      • 客户端处理响应并重新启动 XHR
      • 服务器生成进程并定期检查更新
    • 如果 5 分钟后没有更新:
      • 服务器发送响应并退出衍生进程
      • 客户端进程(空)响应重启 XHR
      • 服务器生成新进程并开始检查
    • 如果必须发送一些更新:服务器发送响应
    • [...]
    • 如果 5 分钟后没有更新:
    • [...]
    • 直到客户端断开连接(= 服务器响应后没有新的 XHR)

    【讨论】:

    • 感谢您的回复。延迟实际上是 500 毫秒,即 0.5 秒。请注意,只要客户端的浏览器打开页面,此脚本就会开始执行检查和更新的例行程序。如果有例如1000 个客户端浏览器同时打开,服务器必须不断地向所有浏览器发送响应。如果任何客户端断开连接,我们如何检查 php 脚本并为它们停止脚本,保持脚本对所有其他在线客户端打开。请解释
    • 仍在等待您的回复(因为看起来这里只有少数人知道长轮询为什么我没有得到任何其他答案)。请与我分享您的 longpoll 技术。我将不胜感激。如果任何客户端断开连接,我们如何检查 php 脚本并为它们停止脚本,保持脚本对所有其他在线客户端打开。请帮忙!
    • 我已经为我的问题添加了一些解释,请查看
    • 确实在我的回答中描述了如何防止服务器保持打开脚本引擎的所有实例。请仔细阅读答案。我会尽量让它更明确。
    【解决方案2】:

    是的,这是一种简单方便的方法,它不是正确的方法,但不是最好的主意。因为随着用户的增加,它会受到影响并且会导致很多问题。

    对于共享主机来说,这样做不是一个好主意,这种方法只有在用户数量不多并且你有自己的服务器的情况下才能正常工作。如果您在共享主机服务器中使用这种方法,那么您可能会遇到使用的最大服务器资源,或会话锁定问题,并且http 服务可能会在一段时间内不可用。

    或者您可以使用现有的 api,用于聊天应用程序,或者拥有一个可以运行脚本的专用服务器,例如 node.js 和类似的服务器模块

    【讨论】:

    • 感谢您的回答和提示。
    猜你喜欢
    • 2015-07-15
    • 2014-01-11
    • 1970-01-01
    • 1970-01-01
    • 2011-05-01
    • 2011-03-20
    • 2012-11-25
    • 2011-06-18
    • 1970-01-01
    相关资源
    最近更新 更多