在 Laravel Vapor 上使用 Laravel Echo (Pusher)
Using Laravel Echo (Pusher) on Laravel Vapor
我很难找出为什么我的事件不是 "triggered" 在前端(Laravel Echo + Pusher),我的应用程序是通过 Laravel Vapor 部署的,即使它在当地锻炼得很好。
Pushers debug console 实际上表明事件实际上是由 Laravel 应用程序发送给 Pusher。
因为我几乎浪费了大约半天的时间来找出问题所在(幸运的是,我看到我的消息实时显示在我的本地环境中,而不是在 post 暂存一些东西之后暂存), 虽然我会再花 10 分钟在这里写一个 post 这样一些人(希望)不需要浪费那么多时间。
实际问题如下:
- Vapor 首先在
.vapor
目录中本地构建应用程序。
- 在此构建过程中加载的
.env
中的 PUSHER 键是您本地 .env
(!) 中的键,这意味着如果您设置 [=15] 它不会改变任何内容=] 和 MIX_PUSHER_APP_CLUSTER
环境变量在你的 .env.{environment}
中(你从 运行 vapor env:pull {environment}
.
我以一种快速(而且肮脏)的方式解决了这个问题:
- 再添加几个环境变量:
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=eu
# Necessary in `php artisan pusher:credentials`
PUSHER_LOCAL_APP_KEY=
PUSHER_LOCAL_APP_CLUSTER=eu
# Necessary in `php artisan pusher:credentials`
PUSHER_STAGING_APP_KEY=
PUSHER_STAGING_APP_CLUSTER=eu
# Necessary in `php artisan pusher:credentials`
PUSHER_PRODUCTION_APP_KEY=
PUSHER_PRODUCTION_APP_CLUSTER=eu
MIX_PUSHER_APP_KEY="${PUSHER_LOCAL_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_LOCAL_APP_CLUSTER}"
- 向 Vapor 构建过程添加新命令(在
yarn run production
之前):php artisan pusher:credentials {environment}
。因此,对于分期,您将使用 php artisan pusher:credentials staging
.
命令如下所示:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Console\ConfirmableTrait;
use Illuminate\Support\Str;
final class SwapPusherCredentials extends Command
{
use ConfirmableTrait;
private array $keyPatterns = [
'PUSHER_%sAPP_KEY',
'PUSHER_%sAPP_CLUSTER',
];
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'pusher:credentials {environment=production}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Sets the pusher credentials based on the current environment';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @throws \Exception
*/
public function handle()
{
// Basically we're fixing a bug (?) in Vapor. Since we're building the front end locally,
// we need to swap the pusher keys before building. If we don't do this, the front end
// will be built with local pusher keys. When posting messages not local it's broken
$environment = Str::upper($this->argument('environment'));
$this->updatePusherEnvironmentVariables($environment);
}
/**
* @param string $environment
* @throws \Exception
*/
private function updatePusherEnvironmentVariables(string $environment)
{
foreach ($this->keyPatterns as $pattern) {
// 'PUSHER_LOCAL_APP_KEY' || 'PUSHER_STAGING_APP_KEY' etc.
$variableToSet = sprintf($pattern, $environment . '_');
// 'PUSHER_APP_KEY'
$targetVariableName = sprintf($pattern, '');
if (!env($targetVariableName, false)) {
throw new \Exception('Missing environment value for ' . $targetVariableName);
}
$this->setVariable($targetVariableName, $variableToSet);
}
}
private function setVariable(string $targetVariableName, string $variableToSet)
{
file_put_contents($this->laravel->environmentFilePath(), preg_replace(
$this->replacementPattern($targetVariableName),
$replacement = '${' . $variableToSet . '}',
file_get_contents($this->laravel->environmentFilePath())
));
$this->info("Successfully set MIX_{$targetVariableName} to {$replacement}!");
}
private function replacementPattern(string $targetVariableName)
{
// Don't remove notsurebutfixes, when removed it doesn't match the first entry
// So it will match all keys except PUSHER_LOCAL_* for some reason.
$escaped = '\=notsurebutfixes|$\{' . $this->insertEnvironmentIntoKey('LOCAL',
$targetVariableName) . '\}|$\{' . $this->insertEnvironmentIntoKey('STAGING',
$targetVariableName) . '\}|$\{' . $this->insertEnvironmentIntoKey('PRODUCTION',
$targetVariableName) . '\}';
return "/^MIX_$targetVariableName{$escaped}/m";
}
// Insert the environment after PUSHER_ in any PUSHER_* like variable passed in.
// So basically PUSHER_APP_KEY => PUSHER_LOCAL_APP_KEY
private function insertEnvironmentIntoKey($environment, $key)
{
$parts = explode('_', $key, 2);
return $parts[0] . '_' . $environment . '_' . $parts[1];
}
}
就是这样。现在 .vapor
目录中的 .env
文件将在部署期间更新以使用 PUSHER_STAGING_APP_KEY
和 PUSHER_STAGING_APP_CLUSTER
!
我已经花了 小时 试图找出同样的问题,但我即将失去它。
我刚刚发现这个 post 描述了一个有助于解决这个问题的 npm 包。
来源
https://codinglabs.com.au/blog/2019/8/using-environment-specific-variables-in-laravel-vapor-with-mix
我很难找出为什么我的事件不是 "triggered" 在前端(Laravel Echo + Pusher),我的应用程序是通过 Laravel Vapor 部署的,即使它在当地锻炼得很好。
Pushers debug console 实际上表明事件实际上是由 Laravel 应用程序发送给 Pusher。
因为我几乎浪费了大约半天的时间来找出问题所在(幸运的是,我看到我的消息实时显示在我的本地环境中,而不是在 post 暂存一些东西之后暂存), 虽然我会再花 10 分钟在这里写一个 post 这样一些人(希望)不需要浪费那么多时间。
实际问题如下:
- Vapor 首先在
.vapor
目录中本地构建应用程序。 - 在此构建过程中加载的
.env
中的 PUSHER 键是您本地.env
(!) 中的键,这意味着如果您设置 [=15] 它不会改变任何内容=] 和MIX_PUSHER_APP_CLUSTER
环境变量在你的.env.{environment}
中(你从 运行vapor env:pull {environment}
.
我以一种快速(而且肮脏)的方式解决了这个问题:
- 再添加几个环境变量:
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=eu
# Necessary in `php artisan pusher:credentials`
PUSHER_LOCAL_APP_KEY=
PUSHER_LOCAL_APP_CLUSTER=eu
# Necessary in `php artisan pusher:credentials`
PUSHER_STAGING_APP_KEY=
PUSHER_STAGING_APP_CLUSTER=eu
# Necessary in `php artisan pusher:credentials`
PUSHER_PRODUCTION_APP_KEY=
PUSHER_PRODUCTION_APP_CLUSTER=eu
MIX_PUSHER_APP_KEY="${PUSHER_LOCAL_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_LOCAL_APP_CLUSTER}"
- 向 Vapor 构建过程添加新命令(在
yarn run production
之前):php artisan pusher:credentials {environment}
。因此,对于分期,您将使用php artisan pusher:credentials staging
.
命令如下所示:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Console\ConfirmableTrait;
use Illuminate\Support\Str;
final class SwapPusherCredentials extends Command
{
use ConfirmableTrait;
private array $keyPatterns = [
'PUSHER_%sAPP_KEY',
'PUSHER_%sAPP_CLUSTER',
];
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'pusher:credentials {environment=production}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Sets the pusher credentials based on the current environment';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @throws \Exception
*/
public function handle()
{
// Basically we're fixing a bug (?) in Vapor. Since we're building the front end locally,
// we need to swap the pusher keys before building. If we don't do this, the front end
// will be built with local pusher keys. When posting messages not local it's broken
$environment = Str::upper($this->argument('environment'));
$this->updatePusherEnvironmentVariables($environment);
}
/**
* @param string $environment
* @throws \Exception
*/
private function updatePusherEnvironmentVariables(string $environment)
{
foreach ($this->keyPatterns as $pattern) {
// 'PUSHER_LOCAL_APP_KEY' || 'PUSHER_STAGING_APP_KEY' etc.
$variableToSet = sprintf($pattern, $environment . '_');
// 'PUSHER_APP_KEY'
$targetVariableName = sprintf($pattern, '');
if (!env($targetVariableName, false)) {
throw new \Exception('Missing environment value for ' . $targetVariableName);
}
$this->setVariable($targetVariableName, $variableToSet);
}
}
private function setVariable(string $targetVariableName, string $variableToSet)
{
file_put_contents($this->laravel->environmentFilePath(), preg_replace(
$this->replacementPattern($targetVariableName),
$replacement = '${' . $variableToSet . '}',
file_get_contents($this->laravel->environmentFilePath())
));
$this->info("Successfully set MIX_{$targetVariableName} to {$replacement}!");
}
private function replacementPattern(string $targetVariableName)
{
// Don't remove notsurebutfixes, when removed it doesn't match the first entry
// So it will match all keys except PUSHER_LOCAL_* for some reason.
$escaped = '\=notsurebutfixes|$\{' . $this->insertEnvironmentIntoKey('LOCAL',
$targetVariableName) . '\}|$\{' . $this->insertEnvironmentIntoKey('STAGING',
$targetVariableName) . '\}|$\{' . $this->insertEnvironmentIntoKey('PRODUCTION',
$targetVariableName) . '\}';
return "/^MIX_$targetVariableName{$escaped}/m";
}
// Insert the environment after PUSHER_ in any PUSHER_* like variable passed in.
// So basically PUSHER_APP_KEY => PUSHER_LOCAL_APP_KEY
private function insertEnvironmentIntoKey($environment, $key)
{
$parts = explode('_', $key, 2);
return $parts[0] . '_' . $environment . '_' . $parts[1];
}
}
就是这样。现在 .vapor
目录中的 .env
文件将在部署期间更新以使用 PUSHER_STAGING_APP_KEY
和 PUSHER_STAGING_APP_CLUSTER
!
我已经花了 小时 试图找出同样的问题,但我即将失去它。
我刚刚发现这个 post 描述了一个有助于解决这个问题的 npm 包。
来源 https://codinglabs.com.au/blog/2019/8/using-environment-specific-variables-in-laravel-vapor-with-mix