huang-yi / shadowfax Goto Github PK
View Code? Open in Web Editor NEWRun Laravel on Swoole.
License: MIT License
Run Laravel on Swoole.
License: MIT License
我参考适配器的代码,加了TymonJwtAuthCleaner;并且在配置中的abstracts加了以下配置:
启动服务之后,使用不同用户token获得的用户信息还是同一个。
Event 事件如何在协程总使用?Event::listen('backend.menu.extendItems'), 无法触发事件。
QueryLoggerServiceProvider.php
DB::listen(function (QueryExecuted $query) {
if ($query->time < $this->app['config']->get('logging.query.slower_than', 0)) {
return;
}
$sqlWithPlaceholders = str_replace(['%', '?'], ['%%', '%s'], $query->sql);
$bindings = $query->connection->prepareBindings($query->bindings);
$pdo = $query->connection->getPdo();
$realSql = $sqlWithPlaceholders;
$duration = $this->formatDuration($query->time / 1000);
if (count($bindings) > 0) {
$realSql = vsprintf($sqlWithPlaceholders, array_map([$pdo, 'quote'], $bindings));
}
Log::debug(sprintf('[%s] [%s] %s | %s: %s', $query->connection->getDatabaseName(), $duration, $realSql,
request()->method(), request()->getRequestUri()));
});
日志
[2020-11-27 23:18:23] local.DEBUG: [test] [500μs] select * from `products` where `products`.`id` = '4' limit 1 | POST: /v1/orders
[2020-11-27 23:18:23] local.DEBUG: [test] [500μs] select * from `products` where `products`.`id` = '4' limit 1 | POST: /v1/orders
[2020-11-27 23:18:23] local.DEBUG: [test] [500μs] select * from `products` where `products`.`id` = '4' limit 1 | POST: /v1/orders
[2020-11-27 23:18:23] local.DEBUG: [test] [500μs] select * from `products` where `products`.`id` = '4' limit 1 | POST: /v1/orders
[2020-11-27 23:18:23] local.DEBUG: [test] [500μs] select * from `products` where `products`.`id` = '4' limit 1 | POST: /v1/orders
[2020-11-27 23:18:23] local.DEBUG: [test] [500μs] select * from `products` where `products`.`id` = '4' limit 1 | POST: /v1/orders
[2020-11-27 23:18:23] local.DEBUG: [test] [500μs] select * from `products` where `products`.`id` = '4' limit 1 | POST: /v1/orders
[2020-11-27 23:18:23] local.DEBUG: [test] [500μs] select * from `products` where `products`.`id` = '4' limit 1 | POST: /v1/orders
[2020-11-27 23:18:23] local.DEBUG: [test] [500μs] select * from `products` where `products`.`id` = '4' limit 1 | POST: /v1/orders
[2020-11-27 23:18:23] local.DEBUG: [test] [500μs] select * from `products` where `products`.`id` = '4' limit 1 | POST: /v1/orders
[2020-11-27 23:18:23] local.DEBUG: [test] [390μs] select * from `product_skus` where `product_skus`.`id` = '2' limit 1 | POST: /v1/orders
[2020-11-27 23:18:23] local.DEBUG: [test] [390μs] select * from `product_skus` where `product_skus`.`id` = '2' limit 1 | POST: /v1/orders
[2020-11-27 23:18:23] local.DEBUG: [test] [390μs] select * from `product_skus` where `product_skus`.`id` = '2' limit 1 | POST: /v1/orders
[2020-11-27 23:18:23] local.DEBUG: [test] [390μs] select * from `product_skus` where `product_skus`.`id` = '2' limit 1 | POST: /v1/orders
[2020-11-27 23:18:23] local.DEBUG: [test] [390μs] select * from `product_skus` where `product_skus`.`id` = '2' limit 1 | POST: /v1/orders
[2020-11-27 23:18:23] local.DEBUG: [test] [390μs] select * from `product_skus` where `product_skus`.`id` = '2' limit 1 | POST: /v1/orders
[2020-11-27 23:18:23] local.DEBUG: [test] [390μs] select * from `product_skus` where `product_skus`.`id` = '2' limit 1 | POST: /v1/orders
[2020-11-27 23:18:23] local.DEBUG: [test] [390μs] select * from `product_skus` where `product_skus`.`id` = '2' limit 1 | POST: /v1/orders
[2020-11-27 23:18:23] local.DEBUG: [test] [390μs] select * from `product_skus` where `product_skus`.`id` = '2' limit 1 | POST: /v1/orders
[2020-11-27 23:18:23] local.DEBUG: [test] [390μs] select * from `product_skus` where `product_skus`.`id` = '2' limit 1 | POST: /v1/orders
现在项目中使用了Laravel Module,
使项目中各功能可以以模块进行划分, 每个模块就是一个服务提供者.
现在的情况是, 在php shadowfax start启动后, 各模块没有加载到provider.
➜ php shadowfax start
Starting the Shadowfax server: 127.0.0.1:1215
[√] master process started. [1624]
[√] manager process started. [1632]
[√] worker process started. [1636]
[√] worker process started. [1637]
[√] worker process started. [1635]
[√] worker process started. [1639]
[√] worker process started. [1634]
[√] worker process started. [1640]
[√] worker process started. [1638]
[√] worker process started. [1633]
[2020-06-17 19:51:12] 127.0.0.1 [404]: POST https://a.work.test/api/mm/signing [36.73ms]
[2020-06-17 19:51:22] 127.0.0.1 [404]: POST https://a.work.test/api/mm/auth/login [1.93ms]
如以上两条路由是由mm模块定义, 但是无法访问到.
按照文档配置,然后进行测试,发现大并发下,Redis::get()的时候报错了:Socket#13 has already been bound to another coroutine#1156, reading of the same socket in coroutine#1154 at the same time is not allowed.
跟踪代码后发现,连接池并没有被使用,Redis::get()还是在使用laravel自己的RedisMamager。所以出现了同时使用连接的情况。
然后发现,根本原因是,Laravel自带的RedisServiceProvider,implements了DeferrableProvider,会被滞后加载。
而且,加载时使用了app->singleton,而不是app->singletonIf,所以会直接替换shadowfax注入的RedisMamager。
我临时的解决办法,拷贝Illuminate\Redis\RedisServiceProvider的代码,新建一个自己的RedisServiceProvider,并且把app->singleton改成app->singletonIf,或者去掉implements DeferrableProvider。然后在放入config.app里面。两个方法都可以解决问题,把连接交给连接池分配,实现协程安全。
虽然问题解决了,但总感觉这样操作不太优雅。毕竟,作为一个胶水程序员,我恨不得只用composer就可以做完项目。
我是个Laravel彩笔,不知道有没有什么方法直接在shadowfax里面搞定,而不用新增一个RedisServiceProvider,以及修改config.app
route/api.php
$router->any('wechat', 'WechatController@serve');
Controllers/WechatController.php
/**
* @return Response
* @throws BadRequestException
* @throws InvalidArgumentException
* @throws InvalidConfigException
* @throws ReflectionException
*/
public function serve()
{
$app = Factory::miniProgram(config('mm.mini_program'));
$app->server->push(static function ($message){
return "您好!欢迎使用 EasyWeChat";
});
return $app->server->serve();
}
GET
访问 api/wechat
404, 没有异常报错. 无法通过微信的验证请求. PHP-FPM
情况下, 是正常的.
注释 serve()
方法中的代码, 直接返回 response()->json()
是正常.
php version: 7.4.7
os: macbook pro 10.15.5 (19F101)
[2020-06-17 16:59:16 *93899.7] ERROR php_swoole_server_rshutdown (ERRNO 503): Fatal error: Uncaught ErrorException: array_key_exists() expects parameter 2 to be array, null given in /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php:151
Stack trace:
#0 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(2, 'array_key_exist...', '/Users/wenber/h...', 151, Array)
#1 /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php(151): array_key_exists('client', NULL)
#2 /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php(249): Illuminate\Support\Arr::exists(NULL, 'client')
#3 /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php(487): Illuminate\Support\Arr::forget(NULL, Array)
#4 /Users/wenber/htdocs/work/socialab/vendor/huang-yi/shadowfax/src/Listeners/FrameworkBootstrappedEvent/OverrideRedisManager.php(26): Illuminate\Support\Arr::pull(NULL, 'client', 'phpredis')
#5 /Users/wenber/htdocs/work/socialab/vendor/huang-yi/shadowfax/ in /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php on line 151
147| if ($array instanceof ArrayAccess) {
148| return $array->offsetExists($key);
149| }
150|
151| return array_key_exists($key, $array);
152| }
153|
154| /**
155| * Return the first element in an array passing a given truth test.
147| if ($array instanceof ArrayAccess) {
148| return $array->offsetExists($key);
149| }
150|
151| return array_key_exists($key, $array);
152| }
153|
154| /**
155| * Return the first element in an array passing a given truth test.
+1 vendor frames
+1 vendor frames
2 [internal]:0
Whoops\Run::handleShutdown()
2 [internal]:0
Whoops\Run::handleShutdown()
[2020-06-17 16:59:16 *93904.4] ERROR php_swoole_server_rshutdown (ERRNO 503): Fatal error: Uncaught ErrorException: array_key_exists() expects parameter 2 to be array, null given in /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php:151
Stack trace:
#0 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(2, 'array_key_exist...', '/Users/wenber/h...', 151, Array)
#1 /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php(151): array_key_exists('client', NULL)
#2 /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php(249): Illuminate\Support\Arr::exists(NULL, 'client')
#3 /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php(487): Illuminate\Support\Arr::forget(NULL, Array)
#4 /Users/wenber/htdocs/work/socialab/vendor/huang-yi/shadowfax/src/Listeners/FrameworkBootstrappedEvent/OverrideRedisManager.php(26): Illuminate\Support\Arr::pull(NULL, 'client', 'phpredis')
#5 /Users/wenber/htdocs/work/socialab/vendor/huang-yi/shadowfax/ in /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php on line 151
[2020-06-17 16:59:16 *93903.2] ERROR php_swoole_server_rshutdown (ERRNO 503): Fatal error: Uncaught ErrorException: array_key_exists() expects parameter 2 to be array, null given in /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php:151
Stack trace:
#0 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(2, 'array_key_exist...', '/Users/wenber/h...', 151, Array)
#1 /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php(151): array_key_exists('client', NULL)
#2 /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php(249): Illuminate\Support\Arr::exists(NULL, 'client')
#3 /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php(487): Illuminate\Support\Arr::forget(NULL, Array)
#4 /Users/wenber/htdocs/work/socialab/vendor/huang-yi/shadowfax/src/Listeners/FrameworkBootstrappedEvent/OverrideRedisManager.php(26): Illuminate\Support\Arr::pull(NULL, 'client', 'phpredis')
#5 /Users/wenber/htdocs/work/socialab/vendor/huang-yi/shadowfax/ in /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php on line 151
Whoops\Exception\ErrorException
Uncaught ErrorException: array_key_exists() expects parameter 2 to be array, null given in /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php:151
Stack trace:
#0 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(2, 'array_key_exist...', '/Users/wenber/h...', 151, Array)
#1 /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php(151): array_key_exists('client', NULL)
#2 /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php(249): Illuminate\Support\Arr::exists(NULL, 'client')
#3 /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php(487): Illuminate\Support\Arr::forget(NULL, Array)
#4 /Users/wenber/htdocs/work/socialab/vendor/huang-yi/shadowfax/src/Listeners/FrameworkBootstrappedEvent/OverrideRedisManager.php(26): Illuminate\Support\Arr::pull(NULL, 'client', 'phpredis')
#5 /Users/wenber/htdocs/work/socialab/vendor/huang-yi/shadowfax/
at vendor/laravel/framework/src/Illuminate/Support/Arr.php:151
147| if ($array instanceof ArrayAccess) {
148| return $array->offsetExists($key);
149| }
150|
151| return array_key_exists($key, $array);
152| }
153|
154| /**
155| * Return the first element in an array passing a given truth test.
PHP Fatal error: Uncaught ErrorException: array_key_exists() expects parameter 2 to be array, null given in /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php:151
Stack trace:
#0 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(2, 'array_key_exist...', '/Users/wenber/h...', 151, Array)
#1 /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php(151): array_key_exists('client', NULL)
#2 /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php(249): Illuminate\Support\Arr::exists(NULL, 'client')
#3 /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php(487): Illuminate\Support\Arr::forget(NULL, Array)
#4 /Users/wenber/htdocs/work/socialab/vendor/huang-yi/shadowfax/src/Listeners/FrameworkBootstrappedEvent/OverrideRedisManager.php(26): Illuminate\Support\Arr::pull(NULL, 'client', 'phpredis')
#5 /Users/wenber/htdocs/work/socialab/vendor/huang-yi/shadowfax/ in /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php on line 151
+1 vendor frames
2 [internal]:0
Whoops\Run::handleShutdown()
[2020-06-17 16:59:16 *93905.1] ERROR php_swoole_server_rshutdown (ERRNO 503): Fatal error: Uncaught ErrorException: array_key_exists() expects parameter 2 to be array, null given in /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php:151
Stack trace:
#0 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(2, 'array_key_exist...', '/Users/wenber/h...', 151, Array)
#1 /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php(151): array_key_exists('client', NULL)
#2 /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php(249): Illuminate\Support\Arr::exists(NULL, 'client')
#3 /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php(487): Illuminate\Support\Arr::forget(NULL, Array)
#4 /Users/wenber/htdocs/work/socialab/vendor/huang-yi/shadowfax/src/Listeners/FrameworkBootstrappedEvent/OverrideRedisManager.php(26): Illuminate\Support\Arr::pull(NULL, 'client', 'phpredis')
#5 /Users/wenber/htdocs/work/socialab/vendor/huang-yi/shadowfax/ in /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php on line 151
[2020-06-17 16:59:16 $93857.0] WARNING swManager_check_exit_status: worker#6[pid=93901] abnormal exit, status=255, signal=0
[2020-06-17 16:59:16 $93857.0] WARNING swManager_check_exit_status: worker#5[pid=93900] abnormal exit, status=255, signal=0
[2020-06-17 16:59:16 $93857.0] WARNING swManager_check_exit_status: worker#7[pid=93899] abnormal exit, status=255, signal=0
[2020-06-17 16:59:16 $93857.0] WARNING swManager_check_exit_status: worker#4[pid=93904] abnormal exit, status=255, signal=0
[2020-06-17 16:59:16 $93857.0] WARNING swManager_check_exit_status: worker#2[pid=93903] abnormal exit, status=255, signal=0
Symfony\Component\ErrorHandler\Error\FatalError
Uncaught ErrorException: array_key_exists() expects parameter 2 to be array, null given in /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php:151
Stack trace:
#0 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(2, 'array_key_exist...', '/Users/wenber/h...', 151, Array)
#1 /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php(151): array_key_exists('client', NULL)
#2 /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php(249): Illuminate\Support\Arr::exists(NULL, 'client')
#3 /Users/wenber/htdocs/work/socialab/vendor/laravel/framework/src/Illuminate/Support/Arr.php(487): Illuminate\Support\Arr::forget(NULL, Array)
#4 /Users/wenber/htdocs/work/socialab/vendor/huang-yi/shadowfax/src/Listeners/FrameworkBootstrappedEvent/OverrideRedisManager.php(26): Illuminate\Support\Arr::pull(NULL, 'client', 'phpredis')
#5 /Users/wenber/htdocs/work/socialab/vendor/huang-yi/shadowfax/
at vendor/laravel/framework/src/Illuminate/Support/Arr.php:151
147| if ($array instanceof ArrayAccess) {
148| return $array->offsetExists($key);
149| }
150|
151| return array_key_exists($key, $array);
152| }
153|
154| /**
155| * Return the first element in an array passing a given truth test.
public下的静态资源访问不到404
我想在控制器里发送数据
Octobercms : https://github.com/octobercms/october
是否可以帮忙解决下兼容问题?
接入微信后台的客服api
route/api.php
$router->any('wechat/serve', 'WechatMiniCustomerController@serve');
控制器方法
public function serve() : Response
{
$app = $this->getMiniProgram();
$customerService = $app->customer_service;
$app->server->push(static function ($message) use ($customerService) {
if (isset($message['MsgType']) && 'miniprogrampage' === $message['MsgType']) {
if ('type=map' === $message['PagePath']) {
$text = new Text(AirdropConstant::CUSTOMER_INTRO_TEXT);
$customerService->message($text)->to($message['FromUserName'])->send();
}
$link = new Link(AirdropConstant::APP_INFO[$message['PagePath']]);
$customerService->message($link)->to($message['FromUserName'])->send();
}
});
return $app->server->serve();
}
在转发给客服后, 客户端收到消息延迟或者接收不到或者在一段时间后, 会收到好多条.
替换为支持协程的Guzzle Handler后, 也会有这些问题.
PHP-FPM下是正常的.
如题,项目中需要用到socket客户端
线上环境中, 生成的分页链接的 base url
莫名成了我的 api
路由文件中的某个路由.
�如:
api.php
$router->get('user/point', 'Controller@getUserPoint');
laravel-admin 的路由为:
$router->name('mm.')->prefix('mm')->group(static function (Router $router) {
$router->resource('questions', 'MM\QuestionsController');
$router->resource('scores', 'MM\ScoresController');
});
laravel-admin 的页面路径为:
https://xxx.cn/backend/mm/scores
生成的表格分页链接就成了:
https://xxx.cn/api/user/point?page=2
https://xxx.cn/api/user/point?page=3
在本地环境中是生成了:
https://localhost/?page=2
https://localhost/?page=3
Task::dispatch($task);
投递任务的时候出现Target class [shadowfax.task] does not exist.错误
依照文档https://shadowfax.huangyi.tech/docs/2.x/task来执行操作
PHP 7.3
Swoole 4.5.2
php shadowfax start --watch
显示以下错误,修改文件无法自动重启服务器。fswatch单独运行正常。
PHP Fatal error: Uncaught HuangYi\Watcher\Exceptions\InvalidOutputException: Error: Unknown event type: 414
in /www/wwwroot/pro.yenomcmf.com/vendor/huang-yi/swoole-watcher/src/Commands/Fswatch.php:124
Stack trace:
#0 /www/wwwroot/pro.yenomcmf.com/vendor/huang-yi/shadowfax/src/Console/StartCommand.php(278): HuangYi\Watcher\Commands\Fswatch->parseEvents('Error: Unknown ...')
#1 [internal function]: HuangYi\Shadowfax\Console\StartCommand->HuangYi\Shadowfax\Console{closure}(7)
#2 [internal function]: Swoole\Event::rshutdown()
#3 {main}
thrown in /www/wwwroot/pro.yenomcmf.com/vendor/huang-yi/swoole-watcher/src/Commands/Fswatch.php on line 124
Fatal error: Uncaught HuangYi\Watcher\Exceptions\InvalidOutputException: Error: Unknown event type: 414
in /www/wwwroot/pro.yenomcmf.com/vendor/huang-yi/swoole-watcher/src/Commands/Fswatch.php:124
Stack trace:
#0 /www/wwwroot/pro.yenomcmf.com/vendor/huang-yi/shadowfax/src/Console/StartCommand.php(278): HuangYi\Watcher\Commands\Fswatch->parseEvents('Error: Unknown ...')
#1 [internal function]: HuangYi\Shadowfax\Console\StartCommand->HuangYi\Shadowfax\Console{closure}(7)
#2 [internal function]: Swoole\Event::rshutdown()
#3 {main}
thrown in /www/wwwroot/pro.yenomcmf.com/vendor/huang-yi/swoole-watcher/src/Commands/Fswatch.php on line 124
当开启协程特性时,由于在Handshake
回调中使用defer触发Open
事件,此时已经退出协程,所以导致在Open
回调中无法使用Swoole\Coroutine\Channel
接口。
第一次尝试laravel+swoole的项目搭建,第一次使用作者的扩展包,感觉一切好神奇。
自己现在本地的虚拟机跑一段时间,如果没什么问题,尝试搬到线上。
感谢作者!
返回回来的 code 一直失效或者二次使用, 导致无法获取用户信息.
log
[2020-10-09 10:14:19] production.ERROR: 获取用户信息失败 {"msg":"Authorize Failed: {\"errcode\":40163,\"errmsg\":\"code been used, hints: [ req_id: GEeEWaMre-GRQona ]\"}"}
[2020-10-09 10:14:20] production.ERROR: 获取用户信息失败 {"msg":"Authorize Failed: {\"errcode\":40029,\"errmsg\":\"invalid code, hints: [ req_id: GEeEUqNre-TL.5ya ]\"}"}
middleware.php
public function handle(Request $request, Closure $next)
{
$session = session(self::SESSION_KEY, []);
// Log::error('user', ['data' => $session]);
if (!$session) {
/** @var Application $officialAccount */
$officialAccount = app('wechat.official_account.wwf');
if ($request->has('code')) {
try {
$user = $officialAccount->oauth->user();
// 存储到session
session([self::SESSION_KEY => $user]);
// 重定向到首页
// return redirect()->to($this->getTargetUrl($request));
return redirect()->route('module.wwf.home');
} catch (AuthorizeFailedException $e) {
Log::error('获取用户信息失败', ['msg' => $e->getMessage()]);
return redirect()->route('module.wwf.home');
}
}
session()->forget(self::SESSION_KEY);
return $officialAccount->oauth->scopes(['snsapi_userinfo'])
->redirect($request->fullUrl());
}
return $next($request);
}
类 HuangYi\Shadowfax\Laravel\RedisManager
中构造方法不适用于 Lumen
public function __construct($app, $driver, array $config, array $poolsConfig = [])
{
if (version_compare($app->version(), '5.7', '<')) {
echo 1;
parent::__construct($driver, $config);
} else {
parent::__construct($app, $driver, $config);
}
$this->poolsConfig = $poolsConfig;
}
在 Lumen
中 $app->version()
返回的是:
public function version()
{
return 'Lumen (8.2.0) (Laravel Components ^8.0)';
}
version_compare()
方法无法正确判断. 所以造成在 大于 5.7 版本中的 Lumen
无法正常使用 Redis
laravel中response方式:
response()->download
response()->streamDownload
shadowfax源码只是这样处理:
/**
* Send the http content.
*
* @param \Swoole\Http\Response $swooleResponse
* @return void
*/
protected function sendContent(SwooleResponse $swooleResponse)
{
$swooleResponse->end($this->illuminateResponse->getContent());
}
而Symfony\Component\HttpFoundation\StreamedResponse中的getContent:
/**
* {@inheritdoc}
*/
public function getContent()
{
return false;
}
如果是StreamedResponse应该调用ob_get_clean()获取内容,然后分段发送才对吧?
Swoole\Http\Response->write(string $data):
RT.
// 报错信息
// Uncaught ReflectionException: Class Encore\Admin\Admin does not have a property named extensions in /data/wwwroot/app.xxx/app/Cleaners/EncoreAdminCleaner.php:22
// Uncaught ReflectionException: Class Encore\Admin\Admin does not have a property named html in /data/wwwroot/app.xxx/app/Cleaners/EncoreAdminCleaner.php:22
// 对应代码:
$admin->setStaticPropertyValue($name, $value);
OS: macOS 10.15.5 (19F101)
PHP: 7.4.7
Laravel: 7.17.1
文档中指出, 如果使用 shadowfax:cleaners
来生成清理类的话, 无需在 shadowfax.yml
中的 cleaners
进行配置.
但是我从 2.6
升级后, 将之前的监听器更为清理器时, 生成的清理器目录并未在 shadowfax.yml
自动配置.
文档中关于对 tymon/jwt-auth
包的清理示例.
app/Cleaners/TymonJwtAuthCleaner.php
public function clean(Container $app) : void
{
$class = LaravelServiceProvider::class;
$provider = new $class;
$method = (new ReflectionObject($provider))->getMethod('extendAuthGuard');
$method->setAccessible(true);
$method->invoke($provider);
}
启动正常. 请求路由时, 报错如下:
2 [internal]:0
Whoops\Run::handleShutdown()
Whoops\Exception\ErrorException
Uncaught ArgumentCountError: Too few arguments to function Illuminate\Support\ServiceProvider::__construct(), 0 passed in /Users/wilbur/htdocs/work/soci/app/Cleaners/TymonJwtAuthCleaner.php on line 22 and exactly 1 expected in /Users/wilbur/htdocs/work/soci/vendor/laravel/framework/src/Illuminate/Support/ServiceProvider.php:41
Stack trace:
#0 /Users/wilbur/htdocs/work/soci/app/Cleaners/TymonJwtAuthCleaner.php(22): Illuminate\Support\ServiceProvider->__construct()
#1 /Users/wilbur/htdocs/work/soci/vendor/huang-yi/shadowfax/src/Listeners/AppPushingEvent/RunCleaners.php(34): App\Cleaners\TymonJwtAuthCleaner->clean(Object(Illuminate\Foundation\Application))
#2 /Users/wilbur/htdocs/work/soci/vendor/huang-yi/shadowfax/src/EventDispatcher.php(61): HuangYi\Shadowfax\Listeners\AppPushingEvent\RunCleaners->handle(Object(HuangYi\Shadowfax\Events\AppPushingEvent))
#3 /Users/wilbur/htdocs/work/soci/vendor/huang-yi/shadowfax/src/HasEventDispatcher.php(26): HuangYi\Shadowfax\EventDispatcher->dispatch
at vendor/laravel/framework/src/Illuminate/Support/ServiceProvider.php:41
37| *
38| * @param \Illuminate\Contracts\Foundation\Application $app
39| * @return void
40| */
> 41| public function __construct($app)
42| {
43| $this->app = $app;
44| }
45|
+1 vendor frames
如题,静态文件不支持么?本地测试的时候没有静态文件,也挺烦
I knew that shadowfax have done many optimizations to laravel on swoole, but I haven't seen similar introductions about laravel octane, do you have time to make a comparison between shadowfax and laravel octane to show the advantage of shadowfax?
ref: https://github.com/laravel/octane
[2020-08-26 15:31:00] production.ERROR: SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. (SQL: select * from `points` order by `score` desc, `score` desc limit 100 offset 0) {"exception":"[object] (Illuminate\\Database\\QueryException(code: HY000): SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. (SQL: select * from `points` order by `score` desc, `score` desc limit 100 offset 0) at /web/project/vendor/laravel/framework/src/Illuminate/Database/Connection.php:671)
[previous exception] [object] (Doctrine\\DBAL\\Driver\\PDOException(code: HY000): SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. at /web/project/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:66)
[previous exception] [object] (PDOException(code: HY000): SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. at /web/project/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:64)
[2020-08-26 15:31:08] production.ERROR: swoole exit {"exception":"[object] (Swoole\\ExitException(code: 0): swoole exit at /web/project/vendor/encore/laravel-admin/src/Grid/Exporters/CsvExporter.php:171)
我又来提问啦, 今天压测api发现, 接口性能多次压测会逐渐下降,
压测接口为 helloWorld 单字符串,
为了重现, 我下载了最新的
这是api.php
Route::get('test', function () {
return 'HelloWorld';
});
这是 shadowfax.yml
配置
name: shadowfax
type: http
host: 127.0.0.1
port: 1215
mode: process
access_log: true
app_pool_capacity: 10
server:
worker_num: 2
enable_coroutine: false
...
下面的没有改动
这里列上三次压测结果, (均为连续压测
第一次
Running 10s test @ http://localhost:1215/api/test
10 threads and 1000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 1.10s 568.27ms 2.00s 57.44%
Req/Sec 106.35 109.94 0.89k 87.24%
4583 requests in 10.03s, 8.28MB read
Socket errors: connect 0, read 0, write 0, timeout 1888
Non-2xx or 3xx responses: 4524
Requests/sec: 457.00
Transfer/sec: 845.78KB
第二次
Running 10s test @ http://localhost:1215/api/test
10 threads and 1000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 0.00us 0.00us 0.00us -nan%
Req/Sec 37.33 32.67 232.00 75.14%
1425 requests in 10.02s, 2.60MB read
Socket errors: connect 0, read 0, write 0, timeout 1425
Non-2xx or 3xx responses: 1425
Requests/sec: 142.23
Transfer/sec: 266.06KB
第三次
Running 10s test @ http://localhost:1215/api/test
10 threads and 1000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 0.00us 0.00us 0.00us -nan%
Req/Sec 28.96 27.29 150.00 81.82%
587 requests in 10.02s, 1.07MB read
Socket errors: connect 0, read 0, write 0, timeout 587
Non-2xx or 3xx responses: 587
Requests/sec: 58.58
Transfer/sec: 109.61KB
作者你好!鄙人现在遇到一个问题,在使用 shadowfax 的端口直接提供服务时,通过浏览器发送 post 请求,会返回 204 状态码(OPTIONS),也没有返回任何内容;但是使用 nginx 转发给 shadowfax 服务,则可以返回 200 状态码和内容。
我在相应的业务代码写了日志,当请求 post 到 shadowfax 的服务端口时,能够完整记录整个执行的过程,但就是没有输出。
系统:alpine 3.12
php: 7.3.27
swoole: 4.6.4-dev
shadowfax: ^2.10
客户端和服务器的域名地址不一样,可能是跨域的问题?如果是,请教一下如何处理?
启用Websocket worker_num为1 , 创建一个websocket链接, 第二个就无法链接,
worker_num = 8 , 则连接8人之后, 就无法继续链接,
不清楚是bug还是机制,我认为应该是bug
laravel/lumen-framework: 8.2.1
overtrue/laravel-wechat: 6.0.0
huang-yi/shadowfax: 2.10.3
获取 easywechat 实例
$wechat = app('wechat.mini_program.default')
$wechat->auth->session($code);
// 报错为: access_token null
$wechat = Factory::miniProgram(config('wechat.mini_program.default'));
$wechat->auth->session($code);
// 报错: access_token null
切换为 php-fpm 后, 就正常了. 之前使用 laravel 没有出现这个问题.
shadowfax和laravel-s,我都部署调试成功了,但是不知道还有什么区别,比如功能上,原理上,运行细节上,可否指点一下
Uncaught TypeError: Argument 2 passed to Illuminate\Redis\RedisManager::__construct() must be of the type array, string given, called in /Users/wangsong/hyperf-skeleton/backend/vendor/huang-yi/shadowfax/src/Laravel/RedisManager.php on line 22 and defined in /U
sers/wangsong/hyperf-skeleton/backend/vendor/laravel/framework/src/Illuminate/Redis/RedisManager.php:41
shadowfax.huangyi.tech
ping shadowfax.huangyi.tech
PING shadowfax.huangyi.tech (140.143.228.98): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
^C
--- shadowfax.huangyi.tech ping statistics ---
3 packets transmitted, 0 packets received, 100.0% packet loss
Whoops\Exception\ErrorException
Uncaught HuangYi\Shadowfax\Exceptions\EntryNotFoundException: app_pool in /Users/wenber/htdocs/work/socialab/vendor/huang-yi/shadowfax/src/Container.php:75
Stack trace:
#0 /Users/wenber/htdocs/work/socialab/vendor/huang-yi/shadowfax/src/helpers.php(23): HuangYi\Shadowfax\Container->make('app_pool')
#1 /Users/wenber/htdocs/work/socialab/vendor/huang-yi/shadowfax/src/Listeners/HasHelpers.php(107): shadowfax('app_pool')
#2 /Users/wenber/htdocs/work/socialab/vendor/huang-yi/shadowfax/src/Listeners/HasHelpers.php(118): HuangYi\Shadowfax\Listeners\RequestEvent\HandleRequest->appPool()
#3 /Users/wenber/htdocs/work/socialab/vendor/huang-yi/shadowfax/src/Listeners/RequestEvent/HandleRequest.php(30): HuangYi\Shadowfax\Listeners\RequestEvent\HandleRequest->handleWithoutException(Object(Closure))
#4 /Users/wenber/htdocs/work/socialab/vendor/huang-yi/shadowfax/src/EventDispatcher.php(61): HuangYi\Shadowfax\Listeners\RequestEvent\HandleRequest->handle(Object(HuangYi\Shadowfax\Events\RequestEvent))
#5 /Users/wenber/htdocs/w
at vendor/huang-yi/shadowfax/src/Container.php:75
71| if (isset($this->bindings[$abstract])) {
72| return $this->instances[$abstract] = $this->bindings[$abstract]($this);
73| }
74|
> 75| throw new EntryNotFoundException($abstract);
76| }
77|
78| /**
79| * Remove a instance from the container.
+1 vendor frames
2 [internal]:0
Whoops\Run::handleShutdown()
[2020-06-25 15:57:08 *23199.1] ERROR php_swoole_server_rshutdown (ERRNO 503): Fatal error: Uncaught HuangYi\Shadowfax\Exceptions\EntryNotFoundException: app_pool in /Users/wenber/htdocs/work/socialab/vendor/huang-yi/shadowfax/src/Container.php:75
Stack trace:
#0 /Users/wenber/htdocs/work/socialab/vendor/huang-yi/shadowfax/src/helpers.php(23): HuangYi\Shadowfax\Container->make('app_pool')
#1 /Users/wenber/htdocs/work/socialab/vendor/huang-yi/shadowfax/src/Listeners/HasHelpers.php(107): shadowfax('app_pool')
#2 /Users/wenber/htdocs/work/socialab/vendor/huang-yi/shadowfax/src/Listeners/HasHelpers.php(118): HuangYi\Shadowfax\Listeners\RequestEvent\HandleRequest->appPool()
#3 /Users/wenber/htdocs/work/socialab/vendor/huang-yi/shadowfax/src/Listeners/RequestEvent/HandleRequest.php(30): HuangYi\Shadowfax\Listeners\RequestEvent\HandleRequest->handleWithoutException(Object(Closure))
#4 /Users/wenber/htdocs/work/socialab/vendor/huang-yi/shadowfax/src/EventDispatcher.php(61): HuangYi\Shadowfax\Listeners\RequestEvent\HandleRequest->handle(Object(HuangYi\Shadowfax\Events\RequestEvent))
#5 /Users/wenber/htdocs/w in /Users/wenber/htdocs/work/socialab/vendor/huang-yi/shadowfax/src/Container.php on line 75
[2020-06-25 15:57:08 $20731.0] WARNING swManager_check_exit_status: worker#1[pid=23199] abnormal exit, status=255, signal=0
php shadowfax start -w
起动时, 在修改 .env
文件时, 会偶现这个问题.
在 bootstrap/helper.php(通过composer加载) 文件中增加了函数, 执行php shadowfax reload后, 发现控制器中还是调用不到 函数? 直接报错 call undefined function xxx ?
BaseController.php
class BaseAgentController extends Controller
{
/**
* @var $user Collection
*/
protected $user;
public function __construct()
{
//执行中间件获取用户信息
$this->middleware(function ($request, $next) {
$this->user = collect(Auth::user())->except(['permissions', 'roles']);
return $next($request);
});
}
}
IndexController.php
class IndexController extends BaseAgentController
{
public function index(Request $request)
{
$user = $this->user;//这个地方有时能够获取到数据,有的时候不能获取到数据,获取到的是NULL
return view('admin.index.index', compact('user'));
}
}
如上在父类的CONTROLLER中的构造函数使用中间件方法给对象属性设置值,在子类的CONTROLLER中有的时候获取不到设置的属性值
最近在调研shadowfax技术方案是发现,如果通过Controller的构造函数注入实例属性的话,由于laravel在请求结束后并不会销毁Controller实例,那么即使在设置中设置了abstract字段也不会重新注入。我们有一些简单的解决方案:
//HandleRequest.php
//other code
$response->send($event->response);
foreach ($app->routes as $route) {
unset($route->controller);
}
//other code
这种方案可以让开发者更加无痛集成shadowfax。不过,我们需要评估这种方案对性能的影响,我个人觉得大多数情况下应该没什么太大影响。或者我们可以在配置文件中提供一个选项clear_controller
,让用户来自己决定是否需要在请求结束后清理控制器。
该包Laravel Admin的 302 跳转请求不生效,
例如增加菜单项, 提交成功后会进行跳转, 控制台打印到了该请求, 但是没有后续反应
[2020-06-19 16:15:46] 127.0.0.1 [302]: POST http://a.work.test/backend/auth/menu [83.28ms]
数据清理监听器: 按照 Laravel-S
<?php
namespace App\Listeners;
use Encore\Admin\Admin;
use HuangYi\Shadowfax\Events\AppPushingEvent;
use Illuminate\Support\Facades\Facade;
class RebindLaravelAdmin
{
public const ADMIN_CLASS = Admin::class;
protected $properties = [
'deferredScript' => [],
'script' => [],
'style' => [],
'css' => [],
'js' => [],
'html' => [],
'headerJs' => [],
'manifestData' => [],
'extensions' => [],
'minifyIgnores' => [],
];
/**
* Handle the event.
*
* @param AppPushingEvent $event
*
* @return void
*/
public function handle(AppPushingEvent $event) : void
{
$reflection = new \ReflectionClass(self::ADMIN_CLASS);
foreach ($this->properties as $name => $value) {
if (property_exists(self::ADMIN_CLASS, $name)) {
$reflection->setStaticPropertyValue($name, $value);
}
}
$event->app->forgetInstance(self::ADMIN_CLASS);
Facade::clearResolvedInstance(self::ADMIN_CLASS);
}
}
刚上线了一个项目, 流量正常
但是在日志中会有以下警告.
WARNING swSignalfd_onSignal (ERRNO 707): Unable to find callback function for signal Broken pipe: 13
我用的Laravel6 但是使用过程发现,提升并不明显
1.我对接口请求次数加了限制,在shadowfax启动后,会提示too many attempts
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.