[javascript]在线聊天室 - Ajax轮询与长轮询
## 什么是轮询轮询即rolling,通过Ajax循环访问服务端直到获取信息返回并关闭连接。
通俗点讲就是连续访问服务器,获取服务端数据并在前端输出。
### Ajax轮询
对于Ajax轮询, 我们可以简单的一笔带过,因为他真的太消耗服务器资源了。
Ajax轮询前端 `index.html`通过每隔一段时间访问后端 `server.php`并通过Jquery更新页面信息,后端负责判断是否有新信息通过json的形式传递给前端,我们来看一个样例:
#### 前端:
```javascript
<script>
function getData() {
$.ajax({
url: 'server.php',
type: 'get',
success: function (data) {
console.log(data);// console输出
}
})
}
setInterval("getData()",1000);//关键点,通过每隔1s访问一次服务器达到获取数据的目的
</script>
```
#### 后端
```php
<?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
<?php
while(true)
{
file_get_contents('server.php');//获取后台数据
sleep(1); //休息一秒继续获取
}
?>
```
### Ajax长轮询
对于聊天室的实现,相比Ajax轮询,Ajax长轮询是一个更好的方式。它优化了客户端与服务端之间的信息获取逻辑。通过前端设置一个较长的超时时间(如60秒),客户端访问一次后端,由后端判断是否存在新消息,如果有则 `echo`出来,没有则将前端挂起(不会断开连接,知道有新消息或到达超时时间)这就完美的解决了消息延迟以及很大程度上缓解了服务器压力。下面我们看一个样例:
#### 前端:
```javascript
function getData() {
$.ajax({
method: 'GET',
url: 'server.php',
timeout: 50000,//50秒延迟
success: function(data) {
console.log(data)
getData(); //关键点,成功之后又发起请求
},
error: function(res) {
getData(); //关键点,失败之后也重新发起请求
}
});
}
getData();
```
#### 后端
```php
<?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
<?php
while(true)
{
if(无数据返回){
等待数据返回(不断开连接)
} else {
有数据返回,返回给前端;
}
}
?>
```
## 完整样例
对于Ajax长轮询我提供了一个完整的样例,包括前端后端,可以直接部署参照.
https://github.com/soxft/xchat dcyln 发表于 2020-8-2 11:18
websocket 他不香吗
websocket的确是个很好的解决方案,这个帖子只是给出一个利用Ajax达到目的的一个方法:lol ytw6176 发表于 2021-8-29 14:23
几年前做过长轮询的场景,不稳定,网页容易崩,不大好处理。。。
仅仅作为一种思路吧,大型场景还是ws比较靠谱 websocket 他不香吗 每天进步一点点,长轮询这个概念之前没接触过{:301_1009:} 厉害了 学到了 之前用轮询做过客服系统,3S 一刷。不过流量比较少,所以还可以接受。 哎,之前是有这么一个想法 但是一直不知道 原来是这样 递归轮询法啊 还可以啊,楼主
页:
[1]
2