1

我做了一个使用文本文件存储数据的朋友聊天,它或多或少都有效,除了当我登录并向某人写一些东西时,什么都没有弹出(但文本存储在适当的文本文件中),然后当我刷新页面从 THEN ON 开始就可以了,但是在另一个浏览器上,作为另一个用户,我还必须刷新页面才能使其正常工作。

基本上,每次登录时,我都必须单击要与之聊天的人的姓名,然后会弹出一个窗口,然后我必须刷新,否则它不起作用。

我想每当我点击一个朋友并想和他聊天时我都必须刷新页面,这是一个会话问题。

这里是 home.php(用户在 index.php 页面登录时被重定向到这里)

<?php
session_start();

if (!isset($_SESSION['user'])) {
    header("Location: index.php");
    exit();
}

?>
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8">

<title></title>
<style type="text/css">@import 'custom_chat.css';</style>
</head>

<body>

<h2>Hello, <?php echo $_SESSION['user']; ?></h2>
<hr>
<p><b>CONTACTS:</b></p>
<?php
require_once 'dbc.php';
$u = $_SESSION['user'];

$q = "SELECT user_id FROM users WHERE username='$u'";
$r = mysqli_query($dbc, $q);
$row = mysqli_fetch_row($r);

// current user id
$uid = $row[0];

$q = "SELECT u.username FROM users AS u, friends AS f 
      WHERE (f.f1 = '$uid' OR f.f2 = '$uid') AND (f.f1 = u.user_id OR f.f2 = u.user_id) AND (u.username != '$u')";
$r = mysqli_query($dbc, $q);


while ($row = mysqli_fetch_assoc($r)) {
    echo '<div class=chat_contacts>';
    echo '<div class='.$row['username'].'>';
    echo '<div class=inner>';
    echo '<div class=inner_chat></div>';
    echo '<form>
              <textarea class=chat_text></textarea> 
          </form>       
          ';
    echo '</div>'; // end .inner
    echo '<a href="#" class='. $row['username'] .'>'.$row['username'] .'</a>
          </div>';
    echo '</div>'; // end .chat_contacts
}

?>

<p><a href="index.php">HOME</a></p>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js"></script>
<script type="text/javascript">

var nc = '<?php echo $u ?>';

// toggle chat window
$('.chat_contacts a').click(function() {
    $(this).prev('div.inner').toggle();
    var tc = $(this).attr('class');
    $(this).parent().parent().addClass(nc+tc);
    $('textarea').focus(); // MD maybe
    return false;
});

// call main chat function
$(function () {
    updateChat(); 
}); // end ready

//update on enter
$('textarea.chat_text').keypress(function(e) {
    $this = $(this); // textarea
    if (e.which == '13') {
        insertChat();



        return false;
    }
});

function insertChat() {
    var text = $this.val();
    $this.val('');
    var ru = $this.parent().parent().parent().attr('class');
    $.post('insert.php',{text:text, ru:ru}, function(data) {
        if (data) {
            alert(data)
        }
    });
}

var timestamp = 0;
function updateChat() {
    $.ajax({
        type: 'GET',
        url: 'update.php?timestamp=' + timestamp,
        async: true,
        cache: false,

        success:function(data) {
            // alert(data);
            var json = eval('('+data+')');
            // if (json['msg'] != null) {
                $('.chat_contacts.'+nc+json['nru']+' .inner_chat').append('<p>'+json['msg']+'</p>'); // MD
            // }
            timestamp = json['timestamp'];
            setTimeout('updateChat()', 1000);
        },
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            // alert('error '+textStatus+'('+errorThrown+')');
            setTimeout('updateChat()', 1000);
        }
    });
}

</script>
</body>
</html>

更新.php

<?php
session_start();
require_once('dbc.php');
error_reporting(E_ALL ^ E_NOTICE);
set_time_limit(0);

$ou = $_SESSION['user'];
$ru = $_SESSION['ru'];
session_write_close();

$q = "SELECT * FROM chats WHERE 
      (chats.f1='$ru' AND chats.f2='$ou') OR (chats.f1='$ou' AND chats.f2='$ru') ORDER BY time DESC LIMIT 1";
$r = mysqli_query($dbc, $q);

// $filename = 'vojaolja.txt';
$q = "SELECT user_id FROM users WHERE username='$ou' 
      ORDER BY user_id DESC LIMIT 1";
$r = mysqli_query($dbc, $q);
$row = mysqli_fetch_row($r);
$fu = $row[0];

$q = "SELECT user_id FROM users WHERE username='$ru' ORDER BY user_id DESC LIMIT 1";
$r = mysqli_query($dbc, $q);
$row = mysqli_fetch_row($r);
$su = $row[0];

$q = "SELECT username FROM users WHERE username='$ru' ORDER BY user_id DESC LIMIT 1";
$r = mysqli_query($dbc, $q);
$row = mysqli_fetch_row($r);
$nru = $row[0];

if ($fu < $su) {
    $filename = $fu.$su.'.txt';
} else {
    $filename = $su.$fu.'.txt';
}

$lastmodif = isset($_GET['timestamp']) ? $_GET['timestamp'] : 0;
$currentmodif = filemtime($filename);

while ($currentmodif <= $lastmodif) {
    usleep(10000);
    clearstatcache();
    $currentmodif = filemtime($filename); 
}

$response = array();

$data = file($filename);
$line = $data[count($data)-1];

$response['msg'] = $line;
$response['nru'] = $nru;
$response['timestamp'] = $currentmodif;

echo json_encode($response);

?>

另外,如果有人想在自己的电脑上重现这个,我可以在这里发布所有代码,它只有几页,可以在 2 分钟内与数据库一起设置。

编辑:

登录后,我会在控制台中看到以下内容:

http://localhost/x_super_chat/update.php?timestamp=0&_=1374509358392 (plus the rolling thingy, it is waiting)

然后我点击一个朋友的名字,弹出窗口,我写了一些东西,我在控制台中得到了这个:

http://localhost/x_super_chat/insert.php

然后当我再次刷新时(当它真正开始工作时)我在控制台中得到以下信息。

http://localhost/x_super_chat/update.php?timestamp=0&_=1374509491493
http://localhost/x_super_chat/update.php?timestamp=1374509435&_=1374509493231 + the waiting thingy icon, it is waiting

所以刷新后它会发生变化,我需要刷新后得到的内容在我登录后立即出现。

编辑2:(在Pitchinnate的回答之后)

登录后,我会在控制台中看到以下内容:

http://localhost/x_super_chat/update.php?timestamp=0&_=1374566749185 (plus the waiting animation)

然后我给另一个人(比如约翰)写了一些东西,我得到了以下信息:

http://localhost/x_super_chat/update.php?timestamp=0&_=1374566749185
http://localhost/x_super_chat/insert.php
http://localhost/x_super_chat/update.php?timestamp=0&_=1374566817682
http://localhost/x_super_chat/update.php?timestamp=1374565160&_=1374566817740
http://localhost/x_super_chat/update.php?timestamp=1374566817&_=1374566817801 (plus waiting animation)

然后,当我在另一边以 John 的身份写一些东西时,我得到以下信息:(这是来自 chrome,所以它与 firebug 中的控制台不同):

http://localhost/x_super_chat/update.php?timestamp=0&_=1374566987051
http://localhost/x_super_chat/insert.php
http://localhost/x_super_chat/update.php?timestamp=1374566995&_=1374567004175
http://localhost/x_super_chat/update.php?timestamp=1374567004&_=1374567004215
4

1 回答 1

0

您可以尝试的一件事是在插入时取消长轮询,在更新函数之外创建一个全局 javascript 变量var myajax;

myajax = $.ajax({
    type: 'GET',
    url: 'update.php?timestamp=' + timestamp,

然后在插入:

function insertChat() {
    myajax.abort();
    var text = $this.val();
    $this.val('');
    var ru = $this.parent().parent().parent().attr('class');
    $.post('insert.php',{text:text, ru:ru}, function(data) {
        if (data) {
            updateChat();
        }
    });
}
于 2013-07-22T17:17:45.110 回答