吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2502|回复: 11
收起左侧

[其他转载] [javascript]在线聊天室 - Ajax轮询与长轮询

  [复制链接]
58172309 发表于 2020-8-2 10:56

什么是轮询

  轮询即rolling,通过Ajax循环访问服务端直到获取信息返回并关闭连接。
通俗点讲就是连续访问服务器,获取服务端数据并在前端输出。

Ajax轮询

  对于Ajax轮询, 我们可以简单的一笔带过,因为他真的太消耗服务器资源了。
  Ajax轮询前端 index.html通过每隔一段时间访问后端 server.php并通过Jquery更新页面信息,后端负责判断是否有新信息通过json的形式传递给前端,我们来看一个样例:

前端:
<script>
      function getData() {
          $.ajax({
              url: 'server.php',
              type: 'get',
              success: function (data) {
                console.log(data);  // console输出
             }
         })
     }
     setInterval("getData()",1000);  //关键点,通过每隔1s访问一次服务器达到获取数据的目的
 </script>
后端
<?php
define('DATABASE','./database.json');
$f = new file();
echo json_decode($f->read(DATABASE),true);
//定义文件类
class file {
/*
  读取函数
 @Param mixed $str  文件路径
*/
  function read($filepath) {
    if (file_exists($filepath)) {
      $str = file_get_contents($filepath);
      return json_decode($str,true);
    } else {
      self::write($filepath,'');
    }
  }
}
?>

  而这种Ajax轮询的方式无论如何都会每1s访问一次服务端,前一次请求完成后,无论有无结果返回,一秒之后下一次请求又会发出。这就叫做Ajax轮询。这边会导致严重消耗服务器资源,并且存在可能1s的延迟问题。(上述示例仅供方法参考,并不是最终样式)我们可以用伪代码来演示以下实现原理:

<?php
  while(true)
  {
    file_get_contents('server.php');  //获取后台数据
    sleep(1);     //休息一秒继续获取
  }
?>

Ajax长轮询

  对于聊天室的实现,相比Ajax轮询,Ajax长轮询是一个更好的方式。它优化了客户端与服务端之间的信息获取逻辑。通过前端设置一个较长的超时时间(如60秒),客户端访问一次后端,由后端判断是否存在新消息,如果有则 echo出来,没有则将前端挂起(不会断开连接,知道有新消息或到达超时时间)这就完美的解决了消息延迟以及很大程度上缓解了服务器压力。下面我们看一个样例:

前端:
    function getData() {
     $.ajax({
         method: 'GET',
         url: 'server.php',
         timeout: 50000,  //50秒延迟
         success: function(data) {
             console.log(data)
             getData();   //关键点,成功之后又发起请求
         },
         error: function(res) {
             getData();   //关键点,失败之后也重新发起请求
         }
     });
 }
 getData();
后端
<?php
define('DATABASE','./database.json');
$f = new file();
echo json_decode($f->read(DATABASE),true);
//定义文件类
class file {
/*
  读取函数
 @param mixed $str  文件路径
*/
  function read($filepath) {
    if (file_exists($filepath)) {
      $str = file_get_contents($filepath);
      return json_decode($str,true);
    } else {
      self::write($filepath,'');
    }
  }
}
?>

  我们可以用伪代码表示:

  <?php
     while(true)
    {
      if(无数据返回){
        等待数据返回(不断开连接)
      } else {
       有数据返回,返回给前端;
      }
    }
  ?>

完整样例

  对于Ajax长轮询我提供了一个完整的样例,包括前端后端,可以直接部署参照.
https://github.com/soxft/xchat

免费评分

参与人数 3吾爱币 +9 热心值 +2 收起 理由
阿木i + 1 + 1 我很赞同!
苏紫方璇 + 7 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
酷酷的dike + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| 58172309 发表于 2020-8-2 11:19
dcyln 发表于 2020-8-2 11:18
websocket 他不香吗

websocket的确是个很好的解决方案,这个帖子只是给出一个利用Ajax达到目的的一个方法
 楼主| 58172309 发表于 2021-8-29 16:18
ytw6176 发表于 2021-8-29 14:23
几年前做过长轮询的场景,不稳定,网页容易崩,不大好处理。。。

仅仅作为一种思路吧,大型场景还是ws比较靠谱
dcyln 发表于 2020-8-2 11:18
徒想er 发表于 2020-8-2 11:24
每天进步一点点,长轮询这个概念之前没接触过
新手张浩 发表于 2020-8-2 11:24
厉害了 学到了
魔幻冰扬 发表于 2020-8-2 11:41
之前用轮询做过客服系统,3S 一刷。不过流量比较少,所以还可以接受。
头像被屏蔽
偶尔平凡 发表于 2020-8-2 11:45
提示: 作者被禁止或删除 内容自动屏蔽
Dream_Peng 发表于 2020-8-2 12:59
哎,之前是有这么一个想法 但是一直不知道   原来是这样
憂殇丶已落幕 发表于 2020-8-2 15:19
递归轮询法啊
田三水 发表于 2020-8-5 09:04
还可以啊,楼主
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 13:08

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表