长轮询聊天系统

3
我知道长轮询是更新聊天内容的最佳方式,我也了解WebSocket,但我认为长轮询更好,因为很多浏览器不支持WebSocket。问题是我不知道如何编写长轮询脚本,我有一个常规的AJAX和常规的PHP GET和POST脚本,那么我该如何使这个PHP代码和AJAX代码以长轮询的方式工作呢?(我不希望它每秒都发出请求,我希望它可以输出数据库中的任何新消息...)

这是我的AJAX代码:

var chat = {}

chat.fetchMessages = function () {
$.ajax({
    url: 'ajax/ajax/chat.php',
    type: 'POST',
    data: { method: 'fetch' },
    success: function(data) {
        $('#chats').html(data);
        $('#chatshere').scrollTop($('#chatshere')[0].scrollHeight);
   }
}); 

}

chat.interval = setInterval(chat.fetchMessages, 1000);
chat.fetchMessages();

以下是我的PHP代码:

<?php
require '../core/init.php';
if(isset($_POST['method']) === true && empty($_POST['method']) === false) {

$chat = new Chat();
$method = trim($_POST['method']);

if($method === 'fetch') {

    $messages = $chat->fetchMessages();

    if(empty($messages) === true) {
        echo 'There is no any messages !';
    }
    else
    {
        foreach($messages as $message) {
        $log_username = $_SESSION['username'];

            if($message['user1'] == $log_username){
            ?>
            <ul class="mychat">
            <li class="first">
            <div class="sOutline">
            <div class="suser">
            <a href="#">
            <img style="height:30px; width:30px;" title="belowfs" alt="belowfs" class="profilepic-belowfs" src="http://demo.scritterscript.com/images/membersprofilepic/thumbs/default-s.jpg">
            </a>
            </div>
            </div>
            </li>                                          
            <li style="margin-left:-5px;">
            <div style="border:1px solid #0099CC; border-radius:5px; background:#0099CC; color:#FFFFFF; padding:7px; max-width:165px;">
            <?php echo nl2br($message['message']); ?>
            </div>
            </li>
            </ul>
            <?php
            }else if($message['user2'] == $log_username){
            ?>
            <ul style="float:right;" class="hischat">
            <li class="first">
            <div class="sOutline">
            <div class="suser">
            <a href="#">
            <img style="height:30px; width:30px;" title="belowfs" alt="belowfs" class="profilepic-belowfs" src="http://demo.scritterscript.com/images/membersprofilepic/thumbs/default-s.jpg">
            </a>
            </div>
            </div>
            </li>                                          
            <li style="margin-right:-5px;">
            <div style="border:1px solid #999; border-radius:5px; background:#999; color:#FFFFFF; padding:7px; max-width:165px;">
            <?php echo nl2br($message['message']); ?>
            </div>
            </li>
            </ul>
            <?php
            }
        }
    }
}
else if($method === 'throw' && isset($_POST['message']) === true) { 
    $message = trim($_POST['message']);
    if(empty($message) === false) {
        $chat->throwMessage($_SESSION['user'], $message);   
    }
}
 }
 ?>

非常感谢您的帮助。


你可能想要了解一下node.jssocket.io - darthmaim
2个回答

2

你可能想要做的是

chat.interval = setInterval(function(){chat.fetchMessages()}, 5000);

替代

chat.interval = setInterval(chat.fetchMessages, 1000);

每5秒获取一次消息。其余部分由您的PHP代码负责输出新消息。


谢谢您的快速回复,但是您能告诉我这会做什么吗? - Yassin
每5秒请求一次。我想我没看清你的问题。对吗? - Ejaz
我认为如果你不打算使用流/套接字,那么你所做的替代方案是正确的。就像它所说的那样,你应该考虑仅在 PHP 脚本中传递新消息,以减少网络流量和响应大小。 - Ejaz
如果我的PHP脚本没有返回任何消息,UI应该将对话视为休眠状态并增加setInterval()的持续时间。同样,在休眠聊天中收到消息时缩短它。 - Ejaz
让我们在聊天中继续这个讨论:http://chat.stackoverflow.com/rooms/27696/discussion-between-ejay-and-magikano - Ejaz
显示剩余6条评论

1

这里有一个链接,详细解释了不同的方法:

什么是长轮询、Websockets、服务器发送事件(SSE)和Comet?

长轮询系统:

  • 客户端使用常规http(参见上面的http)从服务器请求网页。
  • 请求的网页执行javascript,请求来自服务器的文件。
  • 服务器不会立即响应所请求的信息,而是等待新信息可用。
  • 当有新信息可用时,服务器会响应新信息。
  • 客户端接收新信息并立即向服务器发送另一个请求,重新启动该过程。

如果有消息获取的时间间隔,您可能需要查看Ajax轮询部分。


如果包含代码或解决方案,请提供链接,否则该回答可能会失效。 - HaveNoDisplayName

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接