Laravel Ratchet WebSocket回调中调用Cache存储数据不生效问题求解
问题根源及修复方案
核心错误点
- Laravel Cache是门面代理类,仅用于静态调用,你在构造函数中将其注入并手动实例化的操作完全错误,实例化后的空对象没有绑定Laravel实际的缓存管理器,所以put操作看似返回成功,实则没有执行任何实际的存储逻辑。
- Ratchet WebSocket是常驻内存的CLI进程,如果你用web上下文验证缓存是否存在,会存在两个问题:
- 运行artisan命令的系统用户和web服务运行用户不一致,文件缓存的权限隔离会导致你读不到其他用户写入的缓存文件,甚至CLI进程本身没有缓存目录的写入权限。
- 文件缓存本身不适合跨进程高频读写,容易出现文件锁冲突导致写入失败。
修复步骤
- 删掉构造函数中错误的Cache注入和实例化逻辑,直接使用Laravel提供的Cache门面静态方法操作缓存
- 给缓存目录设置正确的读写权限,确保运行artisan命令的用户有权限读写
storage/framework/cache目录:
chmod -R 775 storage/framework/cache # 替换为你实际运行artisan和web服务的用户组 chown -R www:www storage
- 如果需要跨进程共享缓存,建议替换文件缓存为Redis、Memcached等内存缓存驱动,避免权限和文件锁问题。
修复后参考代码
use Illuminate\Support\Facades\Cache; class Ticker extends Command { protected $signature = 'daemon:t'; protected $description = 'Listens to websockets t'; public function __construct() { parent::__construct(); } public function mini(callable $callback) { \Ratchet\Client\connect('wss://stream......')->then(function ($ws) use ($callback) { $ws->on('message', function ($data) use ($ws, $callback) { $json = json_decode($data, true); return call_user_func($callback, $json); }); $ws->on('close', function ($code = null, $reason = null) { echo "....: WebSocket Connection closed! ({$code} - {$reason})" . PHP_EOL; }); }, function ($e) { echo "....: Could not connect: {$e->getMessage()}" . PHP_EOL; }); } public function saveT($t){ try{ foreach ($t as $obj) { Cache::put($obj['s'], $obj, now()->addSeconds(5)); // 本地测试时可打开下方注释验证写入结果 // var_dump(Cache::get($obj['s'])); } } catch (\Exception $exception) { $this->alert($exception->getMessage()); } } public function handle() { $this->mini(function ($json){ Cache::put('s', $json, now()->addSeconds(10)); // 本地测试时可打开下方注释验证写入结果 // var_dump(Cache::get('s')); // $this->saveT($json); try{ Cache::put('test','tested',now()->addSeconds(5)); } catch (\Exception $exception) { $this->alert($exception->getMessage()); } }); } }
内容的提问来源于stack exchange,提问作者Babila Vena
相关产品推荐
相关产品推荐

