我正在从事基本的聊天服务,它基本上是一个学校项目,将在学生中使用.我已经相当成功,但是我遇到了一个问题.更新聊天室.在我的许多测试中,接收消息并使用发送消息的用户可以识别消息的时间通常长达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功能.它跟踪最新的数据抓取,并且仅获取新的聊天信息.这样,一旦数据返回浏览器,它只会加载新内容,而不是整个内容.
在上面的代码中,您似乎每次都在编写整个聊天记录.我确定发生了一些浏览器缓存问题.您可以请求一个返回仅包含最后一个条目的JSON数据(PHP具有内置的JSON函数)的PHP,而不是每次都请求整个html页面,然后将它们附加到文档中.
有关JSON的信息很多.如果您尚未了解它,它是一种表示JavaScript固有数据的方式.它可以将JSON格式的文本本地转换为数组,对象和属性.而且它不像XML那样冗长.
在您的代码中,创建一个名为
var lastDataReceived = "";
这将保留上次从服务器接收到新聊天数据的时间戳.在$.get()成功函数中,将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()时,如果没有新的聊天记录,则回显将返回一个空数组.您可以在JS中对此进行测试.
在这种情况下,您将只添加传入的新项目.因此,您需要向文档中添加新的HTML.使用jQuery超级简单.假设所有聊天都在< div>标签:
<div id="chats">
<!--all chats here-->
</div>
并且您有一个模板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"
});
}
将新的聊天信息发送到服务器时,可以使用相同的数据:jQuery $.post()函数中的{“ chattext”:text ….}类型结构.您将在服务器上需要一个不同的PHP文件,例如addchatdata.php.我已经接触过一种算法,该算法根据是否存在来获取或创建一个聊天室文件.
因此,如果您希望子XML元素看起来像这样
<chat date="04/Jun/2015 13:18:23" name="George">
Here is some of George's text.
</chat>
获得$xml对象后,可以向其添加新的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");
一般来说,这是在做您已经在做的事情:存储来自新聊天的数据,然后将该数据加载到连接到该聊天的其他客户端.但是,这里仅检索新信息,并且将在浏览器上更快地加载.