Ajax asynchronous request to the PHP server, how to achieve non-blocking response original learning and sharing PHP self-study

I recently discovered an ajax asynchronous request problem. When using $.post, $.get, $.ajax to request the PHP server, the data cannot always be returned asynchronously.

After many tests, I found that:
- Different browsers, request different domain names-no blocking: no experimentation
-different browsers, request the same domain name-no blocking: session_id() returns different
-the same browser, request different domain names- Non-blocking: session_id returns different
-same browser, request same domain name-blocking: session_id() returns the same.

Found the problem:
1 Close XDEBUG
2 SESSION lock
3 Clear output buffer

1 Close XDEBUG
XDEBUG is real-time debugging. When debugging, it will maintain FPM to ensure that the thread is working to avoid data pollution. 
The typical test method is to open another browser and visit the site when debugging with XDEBUG. The site is inaccessible at this time. 
This has a major impact on parallel response, that is, even if the front end sends multiple requests, it is controlled by XDEBUG and can only respond to one at the same time. 
In addition, since XDEBUG depends on SESSION, even if you use session_write_close(), you must close the session lock (see below). 
XDEBUG will still open automatically.

2 SESSION lock
Use session_write_close() to close the write lock of SESSION, which is suitable for the situation where SESSION is saved as File.
If SESSION is stored in Redis, it is not needed.

3 Clear the output buffer
Using session_write_close() may not be able to close the SESSION lock immediately, so add ob_end_flush() before this method.
Let session_write_close() take effect immediately.


image
4 Example
There is an example as follows. When the [Submit] button is clicked, the front-end will send two requests to the back-end server.
One is a get request, which is requested every 1 second.
One is a post request, which is sent once at the very beginning, and then waits for the corresponding end.

Look at the HTML code

<form>
<input type="submit" value="提交" />
</form>

<script src="//cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>

<script type="text/javascript">
    $('form').on('submit'function(e{
        e.preventDefault();

        // 每隔一秒请求一次服务器
        var id = setInterval(function({
            $.get(
                'save.php?action=get',
                {},
                function(data{
                    console.log(data);
                },
                'json'
            );
        }, 1000);

        $.post(
            'save.php?action=post',
            {},
            function(data{
                console.log(data);
                // 停止定时循环
                clearInterval(id);
            },
            'json'
        );
    });
</script>


php code

<?php

session_start();

$action = $_GET['action'];

if ($action == 'post') {

   $_SESSION['time'] = 0;
   session_write_close();

    while ($_SESSION['time'] < 5) {
      session_start();
      $_SESSION['time'] = $_SESSION['time'] + 1;

      // 将SESSION数据写入文件中,并关闭写锁
      session_write_close();

      // sleep()模拟花费时间较长的程序,这样在关闭写锁之后,
      // 服务器就能够相应别的请求,如下的$action=get,
      sleep(1);
    }

    echo json_encode([session_id() => $_SESSION['time']]);
    exit();
}

if ($action == 'get') {
    echo json_encode([session_id() => $_SESSION['time']]);
    exit();
}


Guess you like

Origin blog.51cto.com/15127568/2667067