php - 快速可靠地更新聊天室的最佳方法?

标签 php jquery html chat

我正在做一个基本的聊天服务,这基本上是一个学校项目,它将用于学生之间。我很成功,但我有一个问题。更新聊天室。在我的许多测试中,它倾向于使用10秒的时间来接收消息,并被发送消息的用户识别。
运行php将消息推送到chatfile,jquery加载该文件。聊天每3秒更新一次。在我的测试中,聊天文件立即被更新,但是实际的聊天并没有快速更新,平均大约10秒。
我相信这一定是jquery的一个缺陷。我应该离开jquery并找到更好的解决方案,还是我的代码有问题?任何帮助都非常感谢。提前谢谢!
里面也有一些php,只是加载用户名和房间名
jquery代码:

    var roomname = "<?php echo $_GET["room"]; ?>";
    var prevdata = "";
    update();
    setInterval(function(){update()},3000)
    $("#send").click(function(){
        sendMessage();
    });

    $('#message').keyup(function(e){
        if(e.keyCode == 13)
        {
            sendMessage();
        }
    });

    function update()
    {
        $.get("/rooms/room/"+roomname+".html",function(data){
            $("#chatbox").html(data);
            if(prevdata != data && data.indexOf("<?php echo $_SESSION["username"] ?>") != 31)
            {
            playMessageSound();
            }
            prevdata = data;
        });
    }

    function sendMessage()
    {
        var message = $("#message").val();
        $("#message").val("");
        $.get("sendmessage.php?room="+roomname+"&message="+message)
    }

    function playMessageSound()
    {
        var audio = new Audio("/sound/msg.mp3");
        audio.play();
    }

我的解决方案:
我采用了jwatts的解决方案,并对其进行了一些定制,以减少代码行数。我现在只是比较聊天,到文件,并返回差异,将这些附加到聊天,使之尽可能快的更新!
谢谢你们的帮助!

最佳答案

我知道这个问题已经得到了回答,但我想提出另一个可能的解决办法。就这些事情而言,这是一个简单的问题,有一些问题和注意事项,但对于类项目来说,这就足够了。我建议的示例不是我自己创建的,代码是未经测试的。你可能需要一点时间来实现这些改变并让它们工作。
但是它探索了一些基本的数据格式,比如php和javascript中的xml和json功能。它跟踪最新的数据抓取,只获取新的聊天信息。这样,一旦数据返回浏览器,它只加载新的内容,而不是整个内容。
在上面的代码中,每次看起来你都在编写整个聊天。我确信浏览器缓存有问题。不要每次都请求整个html页面,您可以请求一个返回json数据(php有内置的json函数)的php,它只包含最后的条目,然后将这些条目追加到文档中。
关于json有很多可用的信息。如果您还没有了解它,那么它是一种表示javascript本机数据的方式。它可以将json格式的文本本机转换为数组、对象和属性。它不像xml那样冗长。
在代码中,创建一个名为

var lastDataReceived = "";

这将保留上次从服务器接收新聊天数据的时间戳。在$.get()success函数中,将url更改为php页面并将其设置为获取json数据。此外,请输入所需的信息,例如需要数据的房间的名称和上次收到聊天数据的时间:
function update()
{
    $.get({
        url: "/rooms/room/getchatdata.php",
        data: { "room": roomname, "lastDataReceived": lastDataReceived }, 
        success: function(data){
            //..............
        },
        dataType: "json"
    });
}

这将创建一个请求
"/rooms/room/chatdata.php?room="+roomname+"&lastDataReceived="+lastDataReceived 

在服务器端,您可以像这样获取querystring参数
$roomname = $_GET["room"];
$lastDataReceived = date_create_from_format('d/M/Y H:i:s', $_GET["lastDataReceived"]);

看起来您正在将聊天信息写入HTML文件。在本例中,最好使用xml数据。有很多很多php-xml教程。这是w3schools.com上的一个simplexml函数。(http://www.w3schools.com/php/php_ref_simplexml.asp
使用此选项,可以从文件加载:
$xml = simplexml_load_file($roomname.".xml");

如果是新文件室,也可以创建新的XML文件,例如:
<?php
    $chats = <<<XML
        <chats>
        </chats>
        XML;

    $xml = new SimpleXMLElement($chats);
    $xml->saveXML($roomname.".xml");
?>

要确定是否读或写,您可以检查房间是否存在,检查该房间是否存在文件:
$xml = NULL;
if (file_exists($roomname.".xml")) {
    //Set to exsiting
    $xml = simplexml_load_file($roomname.".xml");
} else {
    //Create new file   
    $chats = <<<XML
        <chats>
        </chats>
        XML;
    $xml = new SimpleXMLElement($chats);
    $xml->saveXML($roomname.".xml");
}

无论哪种方式,您都可以使用$xml变量。
现在,假设您已经向服务器发出请求,以查看是否有任何新的聊天数据。您正在使用前面创建的变量$roomname$lastDataReceived。您已经从文件中加载了$xml对象。现在你需要找到任何新的补充。
$chats = $xml->chats->children();
$newchats = array();

foreach($chats as $c) {
    if ($c['date'] > $lastDataReceived) {
        array_push($newchats, $c);
    }
}

现在您有了一个新的聊天项数组,请将json数据写回浏览器:
$json = json_encode($newchats);
header('Content-Type: application/json');
echo $json;

现在回到javascript。在上面的php示例中,$newchats被初始化为一个新数组。当对其调用json_encode()时,如果没有新的聊天记录,echo将返回一个空数组。你可以在js中测试这个。
在本例中,您将只添加进来的新项。所以您需要向文档中添加新的html。使用jquery这非常简单。假设聊天都在<div>标签中:
<div id="chats">
    <!--all chats here-->
</div>

你有一个模板,你想让所有聊天看起来像
<div class="chat_template" style="display:none;">
    <div class="person_name"></div>
    <div class="chat_text"></div>
    <div class="chat_time"></div>
</div>

您可以克隆它,将数据加载到其中,并将其附加到文档中。
function update()
{
    $.get({
        url: "/rooms/room/chatdata.php",
        data: { "room": roomname, "lastDataReceived": lastDataReceived }, 
        success: function(data){
            if (data.length > 0) {
                for (var i = 0; i < data.length; i++) {[
                    var c = data[i];
                    //I do not know what the exact structure of the data will be.
                    // You may need to output the data to the console to see it's structure.
                    // But I am assuming you will have access to the date value, the person's name
                    // and the text.

                    //Clone the template and add the values
                    var div = $("div.chat_template").clone(true);
                    div.find("div.person_name").html(name);
                    div.find("div.chat_text").html(text);
                    div.find("div.chat_time").html(date_val);
                    div.show();

                    //Add the new div to the document
                    $("div#chats").append(div);

                    //Set the last received time for the next query
                    lastDataReceived = date_val;
                }

                playMessageSound();
            }
        },
        dataType: "json"
    });
}

向服务器发送新的聊天信息时,可以在jquerydiv函数中使用相同的data: { "chattext": text....}类型结构。在服务器上需要一个不同的php文件,比如$.post()。我已经提到了一个算法,它基于是否存在聊天室文件来创建或创建聊天室文件。
所以如果您希望子xml元素看起来像这样
<chat date="04/Jun/2015 13:18:23" name="George">
    Here is some of George's text.
</chat>

一旦获得addchatdata.php对象,就可以向其添加新的xml,如下所示:
$chat = $xml->addChild("chat", "Here is some of George's text.");
$chat->addAttribute("date", date('d/M/Y H:i:s'));
$chat->addAttribute("name", "George"); //<--Or use a variable name for the name

//Then save the changes back out to the file:
$xml->saveXML($roomname.".xml");

一般来说,这是在做你已经在做的事情:存储来自新聊天室的数据,然后将这些数据加载到连接到聊天室的其他客户端。然而,在这里它只是检索新的信息,在浏览器上加载速度会快得多。

关于php - 快速可靠地更新聊天室的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30649058/

相关文章:

php - 通过引用将参数可移植地传递给 PHP 的 ReflectionMethod::invokeArgs

php - MySQL 左连接 : Limit parent table

javascript - IE中的jQuery onClick()声音效果和重定向

javascript - 焦点在 android 上不起作用

javascript - jQuery .attr() 对于现有属性返回 "undefined"

php - 使用 PHPDriver 的原则映射示例

php - CakePHP 提交表单以进行正确的操作

javascript - 如何使用 jQuery 禁用单击事件后发生的功能

asp.net - Jquery Ajax Web服务和跨域问题

html - CSS 边框在 IE6 中不起作用