gpt4 book ai didi

php - jQuery 长轮询(使用 PHP 服务器端)

转载 作者:可可西里 更新时间:2023-11-01 12:35:03 26 4
gpt4 key购买 nike

我在这里有点噩梦,所以任何帮助将不胜感激!首先,我将解释我要做什么:

我正在尝试实现一个如下所述的系统:https://stackoverflow.com/a/1086448/1034392在我的本地主机 MAMP 服务器上使用 Yii 框架。我有一个函数可以检查数据库中是否有任何新的通知——如果有,它会解析它们并对它们进行 json 编码。我每 5 秒在一次 while 循环中调用这个函数。

因此:转到/user/unreadNotifications 会触发以下内容

    Yii::log('test'); // to check it's getting called  

$this->layout=false;

header('Content-Type: application/json');

// LONG POLLING
while (Yii::app()->user->getNotifications() == null) {
sleep(5);
}

echo Yii::app()->user->getNotifications(); // prints out json if new notification

Yii::app()->end();

return;

这工作正常 - 转到浏览器中的链接并验证 json 响应 - 一切正常。

然后我尝试了各种 jQuery 东西来让它工作......我发现唯一有效的方法是使用类型为 POST 的 $.ajax 但只有在有等待通知时(因此返回了一些 json)。 $.get$.post 被“中止”(显示在 Firebug 中)但 URL 被调用(因为我可以看到日志文件已更新)- 奇怪。

我使用 $.get 的原始设置是:

        <script type="text/javascript">
function notificationPoll() {
$.get('<?php echo Yii::app()->createUrl('user/unreadNotifications') ?>','', function(result) {
$.each(result.events, function(events) {
alert('New Notification!');
});
notificationPoll();
}, 'json');
}
</script>

<script type="text/javascript">
$(document).ready(function() {
$.ajaxSetup({
timeout: 60 //set a global ajax timeout of a minute
});
notificationPoll();
});
</script>

由于某种原因,这只是“中止”。我已经尝试使用“jsonp”,即使它不是 CORS 请求。但这也不起作用。

这似乎无法取得任何进展!任何人都可以参与吗?

非常感谢

最佳答案

您必须确保函数在合理的时间内终止。你可以做的是:

$ttl = 10;
while ($ttl--) {
$json = Yii::app()->user->getNotifications();
if (null != $json) {
break;
}
sleep(1);
}
if (null == $json) {
$json = json_encode(array(
'nothing' => true
));
}
header('Content-Type: application/json');
echo $json;

Yii::app()->end();
return;

您可以使用 setInterval() 将轮询功能设置为计时器。该函数现在将每隔 10 秒调用一次,您可能需要设置一个信号量以避免在上一次迭代返回之前调用它:

var timer = setInterval(
function() {
if (this.calling) {
return;
}
var fn = this;
fn.calling = true;
$.post(url)
.done(function(data) {
..
})
.always(function() {
fn.calling = false;
});
},
10000
);

然后 AJAX 中的轮询函数需要检查(在 .done())回调中)通知是否存在:

function(data) {
if (data.hasOwnProperty('nothing')) {
alert('No notifications');
return;
}
console.log(data);
...
}

现在一件重要的事情是您的通知是什么样的。这里我假设它是一个 JSON 编码的 string。但如果 Yii 函数返回的是数组或对象,则需要处理其编码。这可能更干净,没有任何 IF:

header('Content-Type: ...
die(json_encode(
array(
'status' => 'success',
'notification' => $json /* This is NULL or an array */
)
// Javascript side we check that data.notification is not null.
));

解码已经由 jQuery 处理,因此上面的变量“data”已经是一个 Javascript 对象,您不需要调用 JSON.parse。不过,您可以检查data 一个对象,并且它具有预期的属性。这将警告您任何错误。

要处理到另一个页面的导航,您可以将轮询 Javascript 函数的 setInterval() 提供的计时器 ID 存储在全局变量中,并在页面调用 时删除计时器onUnload() 停用轮询。

关于php - jQuery 长轮询(使用 PHP 服务器端),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11297035/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com