ajax长轮询时php出现问题

刚接触实时通讯这块,知道用websocket更高效,但我想了解轮询的实现过程,循序渐进


短轮询用定时器setInterval已经实现了,但长轮询时后台进入死循环模块导致整个网站的php网页无响应,比如刷新页面、提交消息都没法进行。具体代码如下:


chat.php:


<div class="chat_content_input">

            <div>

                <textarea name="chat_input" class="chat_input"

                          style="width: 570px;height: 120px;margin: 5px;resize: none"></textarea>

            </div>

            <div style="text-align: right">

                <button class="chat_post">发送</button>

            </div>

</div>

chat.js:


//拉取新消息

            var setting = {

                type: "POST",

                dataType: "html",

                url: "./util/action.php?action=message_pull",

                data: {uid_get: $('#chat_content').attr('uid')},//传递目标用户uid

                success: function (msg) {

                    if (msg.length > 0) {

                        $('.chat_content_list_table').append(msg);//追加消息列表

                    }

                    $.ajax(setting);//立即继续请求

                }

            };

            $.ajax(setting);

action.php中的对应函数:


function message_pull($conn)

{

    session_start();

    session_write_close();//关闭session锁并没有效果,仍被阻塞

    $uid_post = $_SESSION['userinfo'][0]['id'];//发送者,即当前登录用户uid

    $uid_get = $_POST['uid_get'];//消息目标用户uid

    $message_list = '';


    //建立长连接,直到拉取到新消息后断开连接

    while (true) {

        //查询新消息

        foreach (select($conn, 'message', "(uid_get=$uid_post AND uid_post=$uid_get AND read_flag<>1)") as $message) {

            update($conn, 'message', 'read_flag=1', "id={$message['id']}");//每读取一条则将其置为已读状态

            $message_list .= "<tr class='content_list_post' style='text-align: right;font-size: 18px'><td>" . $message['content'] . "</td></tr><tr><td style='text-align: right;font-size: 8px'>" . $message['post_time'] . "</td></tr>";

        }

        if (strlen($message_list) > 0) {

            echo $message_list;//输出新消息

            break;//断开连接

        }else 

            sleep(1);//挂起1s后继续查询

    }

    mysqli_close($conn);

}

参考链接:https://www.cnblogs.com/zhenb...

幕布斯7119047
浏览 460回答 7
7回答

泛舟湖上清波郎朗

虽然不懂php,但从字面上的意思,这当然会死。。。长轮询的意思是把timeout设高,而不是没有timeout,如你代码显示,如果没有新消息就一直是while(true)直接卡死了,应该是没有新消息并且定时器到时了就断掉吧。

慕妹3242003

你请求一次 action.php 就会创建一个php while 就会一直运行 死循环 php当然会死。 是ajax 来请求php 不是php循环去给前台发送消息,你这while 完全没意义。 当你请求后台 后台才查询数据或者更改状态,才正确。

阿波罗的战车

你看到的这样例子的,应该是区分server和worker吧。你的while适用worker进程;接口适合server。另外ajax的长轮询的方式也不是你这样操作。而是依靠前端的定时器,不间断去请求后端。后端渲染数据而已。

吃鸡游戏

post把数据库存表,pull函数有数据了就中断阻塞了,你一直没有数据更新pull函数肯定就是阻塞的
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript