Я пытаюсь создать чат-систему, используя php + ajax + mysql.
<?php session_start(); ?> <html> <head> <title>Live Table Data Edit</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" /> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script> </head> <body> <div class="container"> <br /> <br /> <br /> <div class="table-responsive"> <h3 align="center">You Are : <?php echo $_SESSION['name']; ?></h3><br /> <div id="live_data"></div> </div> <div id="messages"></div> <div class="area" style="display:none"> <textarea id="text" name="text"></textarea> <input type="submit" id="sub" name="sub" value="Send" /> </div> </div> </body> </html> <script> $(document).ready(function() { function fetch_data() { $.ajax({ url: "select.php", method: "POST", success: function(data) { $('#live_data').html(data); } }); } fetch_data(); $(document).on('click', '.first_name', function() { var id = $(this).data("id1"); function fetch_chat() { $.ajax({ url: "fetch_chat.php", method: "POST", data: { id: id }, dataType: "text", success: function(data) { $('#messages').html(data); $("div.area").show(); } }); } function myTimeoutFunction() { fetch_chat(); } myTimeoutFunction(); setInterval(myTimeoutFunction, 1000); fetch_chat(); $("#sub").click(function() { var text = $("#text").val(); $.post('insert_chat.php', { id: id, msg: text }, function(data) { $("#messages").append(data); $("#text").val(''); }); alert(text); }); }); }); </script>
но проблема с этим кодом заключается в том, что он работал только для первого пользователя, с которым я общаюсь, но экран часто мигает, когда я нажимаю на имя других пользователей. например: пользователь 'a' входит в систему и нажимает на пользователя 'b' и запускает чат. все работает нормально до сих пор, но когда пользователь «а» думает пообщаться с другим пользователем «c», вся чат начинает мигать со всеми чатами, хранящимися в базе данных. PLZ скажите мне, где я ошибаюсь.
Для этого нужно полностью переосмыслить, чтобы избавиться от всех возможных ошибок.
Проблема, описанная выше, состоит в том, что вы создаете новый временной интервал каждый раз, когда кто-то нажимает на имя, поэтому постепенно это происходит, и вы запрашиваете каждые несколько миллисекунд, а не каждую секунду. Это неустойчиво. Не нужно декларировать интервалы, функции и т. Д. Внутри обработчика «click» имени. Я думаю, вы делаете это из-за зависимости от идентификатора пользователя, который возникает в результате выбора имени. Однако вы можете преодолеть это, присвоив значение глобальной переменной.
Это означает, что вы можете перемещать все функции за пределы обработчика кликов, устраняя опасность повторного создания одних и тех же интервалов / событий несколько раз. Я также изменил его, чтобы он не использовал интервал. Вместо этого fetch_chat вызывает себя снова через 2 секунды после получения предыдущего ответа. Таким образом, если выборка занимает больше времени, чем обычно, у вас нет нескольких конкурирующих операций выборки, работающих параллельно и вызывающих потенциальную путаницу. Я также увеличил временной интервал на то, что все еще разумно, но не перегрузит сервер.
Вот полный передел кода:
<script> var currentID = null; var chatTimer = null; function fetch_data() { $.ajax({ url: "select.php", method: "POST", success: function(data) { $('#live_data').html(data); fetch_chat(); } }); } function fetch_chat() { $.ajax({ url: "fetch_chat.php", method: "POST", data: { id: currentID }, dataType: "text", success: function(data) { $('#messages').html(data); $("div.area").show(); chatTimer = setTimeout(fetch_chat, 2000); //request the chat again in 2 seconds time } }); } $(document).ready(function() { $(document).on('click', '.first_name', function() { currentID = $(this).data("id1"); //immediately fetch chat for the new ID, and clear any waiting fetch timer that might be pending clearTimeout(chatTimer); fetch_chat(); }); $("#sub").click(function() { var text = $("#text").val(); $.post('insert_chat.php', { id: currentID, msg: text }, function(data) { $("#messages").append(data); $("#text").val(''); }); alert(text); }); fetch_data(); //this will also trigger the first fetch_chat once it completes }); </script>
PS Если вам нужно что-нибудь быстрее, чем обновление за 2 секунды, то вам, вероятно, стоит подумать о повторной архитектуре решения с помощью веб-карт, чтобы получить полную двустороннюю связь, поэтому сервер может «нажимать» элементы чата клиенту, а не клиенту, опросить сервер.
Вы используете setInterval, это неправильно, это запустит цикл каждый раз, когда вы нажимаете на чат, у вас должен быть один цикл, работающий над всеми вашими чатами. Также рассмотрите возможность использования setTimeout вместо setInterval, чтобы убедиться, что вы сначала получите ответ.