Laravel 使用 swoole 协程遇到的坑
14

最近在用laravel-s改造手头上的一个laravel项目,作为这块目前最火的轮子,确实好用,赞一下作者。由于目前所处理的项目需要调用大量api,使用同步串行调用效率低下,因此开始尝试使用swoole的协程客户端来调用api。

这里我本地的环境如下:

Component Version
PHP 7.1.17
Swoole 2.1.2
Laravel Framework 5.5.40

先来个demo体验一下:

<?php

namespace App\Http\Controllers;

class TestController extends Controller
{
    public function index()
    {
        $cli = new \Swoole\Coroutine\Http\Client('127.0.0.1', 80);
        $cli->setHeaders([
            'Host' => 'test.me',
        ]);
        $cli->get('/');
        $result = $cli->body;
        $cli->close();

        return response()->json($result);
    }
}

启动请求之后发现卡死,这下懵逼了,以前在其他地方都是可以用的协程客户端,这里不能用了,WTF。在群里求助,群主提及到不能在魔术方法和call_user_func之类的方法里使用(官方链接)。一语惊醒梦中人,laravel这个框架可是这类方法横行,于是研究了下Controller类的执行方式。框架在执行Controller时,会通过Illuminate\Routing\Controller类的callAction方法执行具体的Controller类的方法,而这个方法如下:

/**
 * Execute an action on the controller.
 *
 * @param string $method
 * @param array  $parameters
 *
 * @return \Symfony\Component\HttpFoundation\Response
 */
public function callAction($method, $parameters)
{
    return call_user_func_array([$this, $method], $parameters);
}

总算找到问题所在了,接下来便是解决问题。其实解决问题的方式swoole的文档里也写了,使用\Swoole\Coroutine::call_user_func\Swoole\Coroutine::call_user_func_array代替即可。那么我们只需要在App\Http\Controllers\Controller中重写一下callAction方法,代码如下:

public function callAction($method, $parameters)
{
    return \Swoole\Coroutine::call_user_func_array([$this, $method], $parameters);
}

注意如果在__call()这样的魔术方法里面需要使用$obj->$method(...$arguments)这种方式去处理用\Swoole\Coroutine::call_user_func_array还是会出现问题。

Done!

目前只是遇到这个坑,以后遇到再更新。

只要全力以赴就无所谓失败

《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 4

切到swoole 4吧, 这个问题就解决了

6个月前

不错

6个月前
XiaohuiLam

@JaguarJack 试了swoole 4如果不修改call_user_func为swoole协程版,将触发报错

Swoole\Coroutine\MySQL::query(): mysql connection#34 is closed. (SQL: select * from users)

我是尝试在swoole 4中使用协程mysql查询

file


经过测试成功了。。。

6个月前

  • 请注意单词拼写,以及中英文排版,参考此页
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
  • 支持表情,使用方法请见 Emoji 自动补全来咯,可用的 Emoji 请见 :metal: :point_right: Emoji 列表 :star: :sparkles:
  • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif
  • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
  请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!