@poroshok_uhodi

Как отслеживать новые записи в бд и выводить их на экран без перезагрузки страницы?

Здравствуйте. пытаюсь написать что то вроде чата. Написал добавление сообщений в бд, и их вывод. Но суть задачи в том, что бы новые сообщение сами выводились на экран без перезагрузки страницы. Это нужно сделать через ajax запрос(по заданию) Ни как не пойму, как прописать логику что бы запрос отслеживал появление новых записей и выводил новые сообщения без перезагрузки. При чём записи могут быть добавлены другими участниками чата.
Это вывод сообщений и разметка формы:
<?php
  $query = $pdo->query('SELECT * FROM `chat`');
  while ($row = $query->fetch(PDO::FETCH_OBJ)){
    echo "<div class='alert alert-info d-flex justify-content-between'><div>$row->message</div><div><em>$row->login</em></div></div>";
  }
  ?>
  <div id="errorBlock" class="error_block alert alert-danger mt-2"></div>
  <form id="chat_form" method="post">
    <label for="message">Ваше сообщение:</label>
    <textarea id="message" type="text" name="message" class="form-control"></textarea>
    <button id="mes_send" class="btn btn-success mt-4" type="button">Отправить!</button>
  </form>


ajax вызывающий код который добавляет записи в бд:
$('#mes_send').click(function () {
		var message = $('#message').val();

	$.ajax({
		url: 'ajax/chat.php',
		type: 'POST',
		cache: false,
		data: {'message' : message},
		dataType: 'html',
		success: function(data) {
			if(data == 'Готово') {
				$('#mes_send').text('Всё готово');
				$('#errorBlock').hide();
				$('#chat_form').trigger('reset');
				setTimeout(function(){
					$('#mes_send').text('Отправить!');
				}, 900);
			}
			else {
				$('#errorBlock').show();
				$('#errorBlock').text(data);
			}
		}
	})
	})


само добавление:
$message = filter_var($_POST['message'], FILTER_SANITIZE_STRING);

    $error ='';

    if(strlen($message) <= 3)
      $error ='Введите нормальное сообщение!';

    if ($error !='') {
      echo $error;
      exit();
    }

    require_once '../mysql_connect.php';

    $sql = 'INSERT INTO chat(message, login) VALUES(:message, :login)';
    $query = $pdo->prepare($sql);
    $query->execute(['message' => $message, 'login' => $_COOKIE['login']]);

    echo "Готово";


Возможно накидал лишнего, но хотелось показать картину в целом. Осталось дописать код который будет отслеживать появление новых записей и выводить их на экран без перезагрузки. Я догадался только использовать функцию setInterval. а как сам запрос сделать не пойму.
setInterval(function() {
	
		$.ajax({
			url: 'ajax/chat_show.php',
			type: 'POST',
			cache: false,
			data: {},
			dataType: 'html',
			success: function(data) {}
		})
		}, 1500);
  • Вопрос задан
  • 398 просмотров
Решения вопроса 1
Вам нужно сделать проверку новых сообщений по интервалу.
let lastMessageId = null
let checkNewMessageInterval = setInterval(() => {
    $.ajax({
      url: 'ajax/checkNewMessage.php',
      type: 'POST',
      cache: false,
      data: {last_id: lastMessageId},
      dataType: 'html',
      success: function(response) {
            let lastMessage = response.data[response.data.length - 1]
            lastMessageId = lastMessage.message_id // сохраняем последнее сообщение которое получили
            // .....
      }
    })
   // ...
}, 5000)


При последнем обновлении, вы можете хранить ID последнего сообщения, а при следующем запросе, получать сообщения только с ID позже сохраненного.

Запрос для БД:
SELECT * FROM chat WHERE `message_id` > $_POST['last_id']


еще лучше, сначала проверять есть ли вообще новые сообщения, и если есть то тогда уже получать эти сообщения:
SELECT COUNT(*) FROM chat WHERE `message_id` > $_POST['last_id']


Это очень простой вариант я описал, но в общем реализация чата через AJAX - это кривой вариант. Вам постоянно придется дергать БД на проверку новых сообщений, и так каждому пользователю.

Лучший и правильный вариант использовать websoket. Используя websoket пользователи будут получать сообщения сразу после их написания, по сути и БД дергать не нужно. Так как БД будет служить только для подгрузки истории сообщений,
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы