模拟在连接上发送buffer时报错

wanyuwei

问题描述

前端使用长链接ajax模拟请求,服务端持续输出响应结果,但是响应结果里面会提示Call to a member function getRemoteIp(),导致无法正确响应

程序代码

public function test(Request $request): Response
{
        // 获取浏览器链接
        $connection = $request->connection;
        for($i=0;$i<=5;$i++){
            $buffer = "我是第{$i}段内容";
            $connection->send(new Chunk($buffer));
            $connection->send(new Chunk(''));
            $connection->send($buffer, true);
            sleep(1); // 暂停1秒
        }
        // 向浏览器发送头部响应
        return response("\n")->withHeaders([
            "Content-Type" => "application/octet-stream",
            "Transfer-Encoding" => "chunked",
        ]);
}

报错信息

我是第4段内容13
我是第5段内容
0

我是第5段内容HTTP/1.1 500 Internal Server Error
Server: workerman
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-Requested-With,Origin
Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS
Connection: keep-alive
Content-Type: text/html;charset=utf-8
Content-Length: 2740

Error: Call to a member function getRemoteIp() on null in /www/wwwroot/test0307.c5html.cn/webman/vendor/workerman/webman-framework/src/Http/Request.php:178
Stack trace:
#0 /www/wwwroot/test0307.c5html.cn/webman/vendor/workerman/webman-framework/src/Http/Request.php(215): Webman\Http\Request->getRemoteIp()
#1 /www/wwwroot/test0307.c5html.cn/webman/vendor/workerman/webman-framework/src/Exception/ExceptionHandler.php(68): Webman\Http\Request->getRealIp()
#2 /www/wwwroot/test0307.c5html.cn/webman/vendor/workerman/webman-framework/src/support/exception/Handler.php(34): Webman\Exception\ExceptionHandler->report()
#3 /www/wwwroot/test0307.c5html.cn/webman/vendor/workerman/webman-framework/src/App.php(261): support\exception\Handler->report()
#4 /www/wwwroot/test0307.c5html.cn/webman/vendor/workerman/webman-framework/src/App.php(343): Webman\App::exceptionResponse()
#5 /www/wwwroot/test0307.c5html.cn/webman/vendor/webman/log/src/Middleware.php(58): Webman\App::Webman\{closure}()
#6 /www/wwwroot/test0307.c5html.cn/webman/vendor/workerman/webman-framework/src/App.php(341): Webman\Log\Middleware->process()
#7 /www/wwwroot/test0307.c5html.cn/webman/app/middleware/AccessControlMiddleware.php(26): Webman\App::Webman\{closure}()
#8 /www/wwwroot/test0307.c5html.cn/webman/vendor/workerman/webman-framework/src/App.php(341): app\middleware\AccessControlMiddleware->process()
#9 /www/wwwroot/test0307.c5html.cn/webman/vendor/workerman/webman-framework/src/App.php(168): Webman\App::Webman\{closure}()
#10 /www/wwwroot/test0307.c5html.cn/webman/vendor/workerman/workerman/Connection/TcpConnection.php(646): Webman\App->onMessage()
#11 /www/wwwroot/test0307.c5html.cn/webman/vendor/workerman/workerman/Events/Select.php(311): Workerman\Connection\TcpConnection->baseRead()
#12 /www/wwwroot/test0307.c5html.cn/webman/vendor/workerman/workerman/Worker.php(1629): Workerman\Events\Select->loop()
#13 /www/wwwroot/test0307.c5html.cn/webman/vendor/workerman/workerman/Worker.php(1423): Workerman\Worker::forkOneWorkerForLinux()
#14 /www/wwwroot/test0307.c5html.cn/webman/vendor/workerman/workerman/Worker.php(1397): Workerman\Worker::forkWorkersForLinux()
#15 /www/wwwroot/test0307.c5html.cn/webman/vendor/workerman/workerman/Worker.php(1779): Workerman\Worker::forkWorkers()
#16 /www/wwwroot/test0307.c5html.cn/webman/vendor/workerman/workerman/Worker.php(1715): Workerman\Worker::monitorWorkersForLinux()
#17 /www/wwwroot/test0307.c5html.cn/webman/vendor/workerman/workerman/Worker.php(562): Workerman\Worker::monitorWorkers()
#18 /www/wwwroot/test0307.c5html.cn/webman/vendor/workerman/webman-framework/src/support/App.php(131): Workerman\Worker::runAll()
#19 /www/wwwroot/test0307.c5html.cn/webman/start.php(4): support\App::run()
#20 {main}

截图报错信息里报错文件相关代码

操作系统及workerman/webman等框架组件具体版本

Linux CentOS7.6
Workerman版本4.1.9
Webman版本1.5.2
php7.4

656 1 0
1个回答

walkor 打赏

写法有问题,如果不熟悉http协议,不要操作connection对象。
http协议先要发送http头,然后是包体,浏览器收到空的Chunk('')就停止收数据了,
你先发了chunk包体,然后发了空的Chunk(''),然后又发字符串,又发包体,再发包头,还用了workerman里明令禁止的sleep,完全乱写。

  • wanyuwei 2023-09-06

    理解了,谢谢大佬

    public function test(Request $request): Response
        {
            // 获取浏览器链接
            $connection = $request->connection;
    
            // 发送响应头部
            $connection->send(response("start\n")->withHeaders([
                "Content-Type" => "application/octet-stream",
                "Transfer-Encoding" => "chunked",
            ]));
    
            for ($i = 0; $i <= 5; $i++) {
                $buffer = "我是第{$i}段内容\n";
                $connection->send(new Chunk($buffer));
            }
    
            // 发送空的Chunk来结束响应
            $connection->send(new Chunk('end'));
            $connection->send(new Chunk(''));
    
    }
年代过于久远,无法发表回答
×
🔝