关于context的一些疑问

dgkerry

问题描述

在例子中,onMessage是一个协程,从这个协程进入新的协Coroutine::create,这个新的协程结束后返回onMessage协程,然后通过context获取user_info是成功,这样做法与user_info保存到一个变量$user_info中,然后进入新协程,协程结束后返回onMessage协程,照样拿到$user_info的值,那context方式跟用变量保存方式好像没什么区别?有没有人知道context主要用在什么样的场景呢?

<?php

use Workerman\Connection\TcpConnection;
use Workerman\Coroutine;
use Workerman\Coroutine\Context;
use Workerman\Events\Swoole;
use Workerman\Protocols\Http\Request;
use Workerman\Worker;
require_once __DIR__ . '/vendor/autoload.php';

$worker = new Worker('http://0.0.0.0:8001');

$worker->eventLoop = Swoole::class; // Or Swow::class or Fiber::class

$worker->onMessage = function (TcpConnection $connection, Request $request) {
    // 在当前协程设置context数据
    Context::set('user_info', ['id' => 1, 'name' => 'name']);
    // 新建协程
    Coroutine::create(function () use ($connection) {
        // 协程间context数据是隔离的,所以新协程里获取的是null
        $userInfo = Context::get('user_info');
        var_dump($userInfo); // 输出null
    });
    // 获取当前协程的context数据
    $userInfo = Context::get('user_info'); // 得到['id' => 1, 'name' => 'name']
    $connection->send(json_encode($userInfo));
};
$worker->onClose = function(TcpConnection $connection)use($worker,&$all_golbal_count)
{
    echo json_encode(Context::get('user_info'))."\n";
    echo connection closed."\n";
};
Worker::runAll();
?>
467 1 1
1个回答

walkor 打赏

简单业务用变量也可以。复杂业务变量需要逐层传入,会很麻烦。

  • wgole 5天前

    我也有这样的疑问,能不能给复杂一点的用例呀?

  • walkor 5天前

    例如你有10个类文件,里面有若干方法,每个方法里需要判断当前用户是谁,可以用 Context::get('user_info'); 获取很方便。
    如果用变量传递,需要给每个方法设定一个参数传递进来,一层一层的传,非常麻烦。

  • nitron 5天前

    比如你在DAL层,model层使用这个变量你就要层层传入,用context则可以直接get而不用传入

🔝