刚接触实时通讯这块,知道用websocket更高效,但我想了解轮询的实现过程,循序渐进
短轮询用定时器setInterval已经实现了,但长轮询时后台进入死循环模块导致整个网站的php网页无响应,比如刷新页面、提交消息都没法进行。具体代码如下:
chat.php:
<div class="chat_content_input">
<div>
<textarea name="chat_input" class="chat_input"
style="width: 570px;height: 120px;margin: 5px;resize: none"></textarea>
</div>
<div style="text-align: right">
<button class="chat_post">发送</button>
</div>
</div>
chat.js:
//拉取新消息
var setting = {
type: "POST",
dataType: "html",
url: "./util/action.php?action=message_pull",
data: {uid_get: $('#chat_content').attr('uid')},//传递目标用户uid
success: function (msg) {
if (msg.length > 0) {
$('.chat_content_list_table').append(msg);//追加消息列表
}
$.ajax(setting);//立即继续请求
}
};
$.ajax(setting);
action.php中的对应函数:
function message_pull($conn)
{
session_start();
session_write_close();//关闭session锁并没有效果,仍被阻塞
$uid_post = $_SESSION['userinfo'][0]['id'];//发送者,即当前登录用户uid
$uid_get = $_POST['uid_get'];//消息目标用户uid
$message_list = '';
//建立长连接,直到拉取到新消息后断开连接
while (true) {
//查询新消息
foreach (select($conn, 'message', "(uid_get=$uid_post AND uid_post=$uid_get AND read_flag<>1)") as $message) {
update($conn, 'message', 'read_flag=1', "id={$message['id']}");//每读取一条则将其置为已读状态
$message_list .= "<tr class='content_list_post' style='text-align: right;font-size: 18px'><td>" . $message['content'] . "</td></tr><tr><td style='text-align: right;font-size: 8px'>" . $message['post_time'] . "</td></tr>";
}
if (strlen($message_list) > 0) {
echo $message_list;//输出新消息
break;//断开连接
}else
sleep(1);//挂起1s后继续查询
}
mysqli_close($conn);
}
之后测试一下,发现一旦php后台进入while循环,就会导致被阻塞,但我看到网上很多demo都这样写,于是感觉很疑惑,谢谢大大们指教
参考链接:https://www.cnblogs.com/zhenb...
7 回答
万千封印
TA贡献1891条经验 获得超3个赞
虽然不懂php,但从字面上的意思,这当然会死。。。长轮询的意思是把timeout
设高,而不是没有timeout
,如你代码显示,如果没有新消息
就一直是while(true)
直接卡死了,应该是没有新消息并且定时器到时了就断掉吧。
米琪卡哇伊
TA贡献1998条经验 获得超6个赞
应该是php的session导致的,session是独占的,所以在长轮训的时候,阻止了同一个client的其他请求,你可以在循环之前加上 session_write_close() 试试,应该就不会阻塞了。
慕桂英4014372
TA贡献1871条经验 获得超13个赞
你请求一次 action.php 就会创建一个php while 就会一直运行 死循环 php当然会死。 是ajax 来请求php 不是php循环去给前台发送消息,你这while 完全没意义。 当你请求后台 后台才查询数据或者更改状态,才正确。
- 7 回答
- 0 关注
- 733 浏览
添加回答
举报
0/150
提交
取消