Чат на php, помогите внедрить Ajax

391
28 июня 2017, 00:54

Здраствуйте, есть вопрос, у меня на одном из сайтов есть рабочий чат на PHP и с базой данных, но он обновляется только при релоаде страницы, тоесть нету Ajax'a, хочу его внедрить, но не знаю как, с самим ajaxом разобрался, но нету идей как его применить, вставлю php код чата, скажите как реализовать обновление сообщений без релоада, возможно переделать код, возможно отслеживать новое сообщение в БД, и тогда запускать Ajax, не знаю, если напишите код, буду признателен.

    <?php
if (isset($_SESSION['loggeduser']) and $_SESSION['loggeduser']['ban status'] <= 0) {
//Берём сообщения с БД
$messages  = mysqli_query($connection, "SELECT * FROM `chat`");
    while ($message = mysqli_fetch_assoc($messages)) {
    //Пока $messages не опустеет, превращаем в строки, и выводим сообщение в отдельном блоке
                $messageId = $message['id'];
                $authorInfo = mysqli_query($connection, "SELECT * FROM `users` WHERE `id` = '".$message['author_id']."' ");
                $author = mysqli_fetch_assoc($authorInfo);
                                        ?>
                //Пока $authorInfo не опустеет, превращаем в строки, и выводим аву и логин автора сообщения
                <div class="message row" id="<?php echo $message['id']?>">
                <div class="col-xs-2 col-sm-2 col-md-2 col-lg-2 messageLeftPart">
                <!--Аватарка автора сообщения в виде фона блока, остальные стили в файле стилей-->
                <div class="authorAvatar" style="background-image: url(../images/uploaded/avatars/<?php if (empty($author['avatar'])){echo 'default.png';} elseif (!empty($author['avatar'])){echo $author['avatar'];} ?>);"></div>
            </div>
            <div class="messageTextAndLogin col-xs-10 col-sm-10 col-md-10 col-lg-10">
            <!--Выводим логин автора в виде ссылки сразу на его профиль-->
            <h4 class="authorLogin"><a href="profile.php?id=<?php echo $author['id']?>"><?php echo $author['login'];?></a></h4>
            <!--Выводим время отравки сообщения-->
            <p class="messageTime"><?php echo $message['time']?></p>
            <!--Выводим текст сообщения-->
            <p class="messageText"><?php echo $message['text'];?></p>
      </div>
</div>
Answer 1

Чат конечно же лучше делать на websocket, но если вы говорите что чат уже есть и его нужно усовершенствовать. Тогда могу посоветовать смотреть в сторону ajax long polling, это непрерывная очередь ожидающих запросов. Вот пример:

<script type="text/javascript">
    function mainLoop(){
        $.ajax({
            url:"handler.php", 
            type:"POST",
            data:{"id":id}, // Предадим id чата.
            cahce:false,
            timeout:30000, // Браузер будет ждать ответ 30 сек, если не получит то цикл перезапустится в error.
            async:true,
            success:function(result){
            $("#response").html(result);
                // Получаем результат.
                setTimeout('mainLoop()',10000);
            },
            error:function(){
                setTimeout('mainLoop()',10000);
            }
        });
    }
    $(document).ready(function(){
        mainLoop(); // Запускаем непрерывный цикл.
    })
</script>

И php обработчик

<?php       
set_time_limit(30);
if (isset($_SESSION['loggeduser']) and $_SESSION['loggeduser']['ban status'] <= 0) {
    while(true){ // Делаем вечный цикл.
        $id = $_POST["id"];
        $getMessage=(mysqli_query("SELECT * FROM `chat` WHERE id> '$id' "));
        if (mysql_num_rows($getMessage)) {
            while($row=mysql_fetch_array($getMessage)){
                // Готовим сообщение.
                // Echo чтото там...
            }
            flush(); // Очистим буфер
            exit; // Прерываем цикл.
        }
        sleep(2); // Перерыв в 2 секунды.
    }
}

На клиенте мы запускаем вечный цикл длинных ajax запросов, клиент делает запрос и ждет 30 сек ответ, если ответ не пришел, он повторяет запрос, если пришел, то мы получаем данные, обновляем их, но запрос все равно повторяется, таким образом мы устанавливаем постоянную связь с сервером. Про ajax long pooling в интернете можно найти много информации и примеров. А на стороне сервера мы делаем вечный цикл в котором раз 2 секунды пытаемся получить сообщение, если сообщение есть то мы прерываем цикл и отдаем данные. Вместо ID сообщения можно использовать метку времени и доставать сообщение у которых метка времени больше чем метка инициализации ajax запроса.

Answer 2

В общем случае это выглядит вот так:

$("form").submit(function(){
    var form=$(this);
    $.ajax({
        method:"post",
        url:form.attr("action")+"&ajax",
        data:form.serialize(),
        cache:false,
        error:function(){
            //do something
        },
        success:function(result){
            //do something
        }
    });
    return false;
});

PHP обрабатывает данные из формы и возвращает ответ от сервера обратно в js

Answer 3

Работаю сейчас с чатами, долго вникал. Итак, если хочешь чат с блекджеком и real-time и есть время писать самому - бери https://socket.io/ или http://socketo.me/
Если времени поменьше и нужны всякие cloud functions типа push notifications- твой выбор http://parseplatform.org/
Если времени совсем мало, нужен готовый чат с чат-румами и прочими прелестями - бери firebase https://firebase.google.com/
По firebase очень много документации, готовых примеров, sdk на всех языках, включая пхп https://firebase-php.readthedocs.io/en/latest/
Надеюсь, инфа была полезной.
P.S. Ajax для чатов - далеко не самое лучшее решение

READ ALSO
Не работает ini_set()

Не работает ini_set()

В чем вообще дело? И так не только с sessionauto_start, но и с другими session

325
Не создается cookie на yii2

Не создается cookie на yii2

Создаю cookie на yii2

207
php replace in url path

php replace in url path

Здравствуйте, как заменить параметры в url path? Есть адрес:

203
Как правильно составить mysql запрос

Как правильно составить mysql запрос

Нужно получить id из таблицы fnews, где userid = $_post['userid'] и newsid = $_post['newsid'], при этом получить ещё userid из таблицы news где id = $_post['newsid']

179