diff --git a/src/app/Console/Commands/Meet/SessionsCommand.php b/src/app/Console/Commands/Meet/SessionsCommand.php --- a/src/app/Console/Commands/Meet/SessionsCommand.php +++ b/src/app/Console/Commands/Meet/SessionsCommand.php @@ -3,6 +3,8 @@ namespace App\Console\Commands\Meet; use App\Console\Command; +use App\Meet\Room; +use App\Meet\Service; class SessionsCommand extends Command { @@ -27,27 +29,10 @@ */ public function handle() { - $client = new \GuzzleHttp\Client([ - 'http_errors' => false, // No exceptions from Guzzle - 'base_uri' => \config('meet.api_url'), - 'verify' => \config('meet.api_verify_tls'), - 'headers' => [ - 'X-Auth-Token' => \config('meet.api_token'), - ], - 'connect_timeout' => 10, - 'timeout' => 10, - ]); + $response = Service::client()->get('sessions')->throwUnlessStatus(200); - $response = $client->request('GET', 'sessions'); - - if ($response->getStatusCode() !== 200) { - return 1; - } - - $sessions = json_decode($response->getBody(), true); - - foreach ($sessions as $session) { - $room = \App\Meet\Room::where('session_id', $session['roomId'])->first(); + foreach ($response->json() as $session) { + $room = Room::where('session_id', $session['roomId'])->first(); if ($room) { $owner = $room->wallet()->owner->email; $roomName = $room->name; diff --git a/src/app/Console/Commands/Status/Health.php b/src/app/Console/Commands/Status/Health.php --- a/src/app/Console/Commands/Status/Health.php +++ b/src/app/Console/Commands/Status/Health.php @@ -141,39 +141,17 @@ $this->line("Checking $url"); try { - $client = new \GuzzleHttp\Client( - [ - 'http_errors' => false, // No exceptions from Guzzle - 'base_uri' => $url, - 'verify' => \config('meet.api_verify_tls'), - 'headers' => [ - 'X-Auth-Token' => \config('meet.api_token'), - ], - 'connect_timeout' => 10, - 'timeout' => 10, - 'on_stats' => function (\GuzzleHttp\TransferStats $stats) { - $threshold = \config('logging.slow_log'); - if ($threshold && ($sec = $stats->getTransferTime()) > $threshold) { - $url = $stats->getEffectiveUri(); - $method = $stats->getRequest()->getMethod(); - \Log::warning(sprintf("[STATS] %s %s: %.4f sec.", $method, $url, $sec)); - } - }, - ] - ); - - $response = $client->request('GET', "ping"); - if ($response->getStatusCode() != 200) { - $code = $response->getStatusCode(); - $reason = $response->getReasonPhrase(); + $response = \App\Meet\Service::client($url)->get('ping'); + if (!$response->ok()) { $success = false; - $this->line("Backend {$url} not available. Status: {$code} Reason: {$reason}"); + $this->line("Backend {$url} not available. Status: " . $response->status()); } } catch (\Exception $exception) { $success = false; - $this->line("Backend {$url} not available. Error: {$exception}"); + $this->line("Backend {$url} not available. Error: " . $exception->getMessage()); } } + return $success; } diff --git a/src/app/Meet/Room.php b/src/app/Meet/Room.php --- a/src/app/Meet/Room.php +++ b/src/app/Meet/Room.php @@ -11,6 +11,7 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Support\Facades\Cache; +use Illuminate\Support\Facades\Http; /** * The eloquent definition of a Room. @@ -56,68 +57,14 @@ /** @var string Database table name */ protected $table = 'openvidu_rooms'; - /** @var \GuzzleHttp\Client|null HTTP client instance */ - private $client = null; - - /** - * Select a Meet server for this room - * - * This needs to always result in the same server for the same room, - * so all participants end up on the same server. - * - * @return string The server url - */ - private function selectMeetServer() - { - $urls = \config('meet.api_urls'); - - $count = count($urls); - - if ($count == 0) { - \Log::error("No meet server configured."); - return ""; - } - - //Select a random backend. - //If the names are evenly distributed this should theoretically result in an even distribution. - $index = abs(intval(hash("crc32b", $this->name), 16) % $count); - - return $urls[$index]; - } - /** * Creates HTTP client for connections to Meet server * - * @return \GuzzleHttp\Client HTTP client instance + * @return HTTP client instance */ private function client() { - if (!$this->client) { - $url = $this->selectMeetServer(); - - $this->client = new \GuzzleHttp\Client( - [ - 'http_errors' => false, // No exceptions from Guzzle - 'base_uri' => $url, - 'verify' => \config('meet.api_verify_tls'), - 'headers' => [ - 'X-Auth-Token' => \config('meet.api_token'), - ], - 'connect_timeout' => 10, - 'timeout' => 10, - 'on_stats' => function (\GuzzleHttp\TransferStats $stats) { - $threshold = \config('logging.slow_log'); - if ($threshold && ($sec = $stats->getTransferTime()) > $threshold) { - $url = $stats->getEffectiveUri(); - $method = $stats->getRequest()->getMethod(); - \Log::warning(sprintf("[STATS] %s %s: %.4f sec.", $method, $url, $sec)); - } - }, - ] - ); - } - - return $this->client; + return Service::clientForRoom($this->name); } /** @@ -127,20 +74,16 @@ */ public function createSession(): ?array { - $params = [ - 'json' => [ /* request params here */ ] - ]; - - $response = $this->client()->request('POST', "sessions", $params); + $response = $this->client()->post('sessions'); - if ($response->getStatusCode() !== 200) { + if ($response->status() !== 200) { $this->logError("Failed to create the meet session", $response); $this->session_id = null; $this->save(); return null; } - $session = json_decode($response->getBody(), true); + $session = $response->json(); $this->session_id = $session['id']; $this->save(); @@ -164,18 +107,14 @@ $url = 'sessions/' . $this->session_id . '/connection'; $post = [ - 'json' => [ - 'role' => $role, - ] + 'role' => $role, ]; - $response = $this->client()->request('POST', $url, $post); - - if ($response->getStatusCode() == 200) { - $json = json_decode($response->getBody(), true); + $response = $this->client()->post($url, $post); + if ($response->status() == 200) { return [ - 'token' => $json['token'], + 'token' => $response->json('token'), 'role' => $role, ]; } @@ -196,11 +135,11 @@ return false; } - $response = $this->client()->request('GET', "sessions/{$this->session_id}"); + $response = $this->client()->get("sessions/{$this->session_id}"); $this->logError("Failed to check that a meet session exists", $response); - return $response->getStatusCode() == 200; + return $response->status() == 200; } /** @@ -295,11 +234,11 @@ 'data' => $data, ]; - $response = $this->client()->request('POST', 'signal', ['json' => $post]); + $response = $this->client()->post('signal', $post); $this->logError("Failed to send a signal to the meet session", $response); - return $response->getStatusCode() == 200; + return $response->status() == 200; } /** @@ -332,7 +271,7 @@ */ private function logError(string $str, $response) { - $code = $response->getStatusCode(); + $code = $response->status(); if ($code != 200) { \Log::error("$str [$code]"); } diff --git a/src/app/Meet/Service.php b/src/app/Meet/Service.php new file mode 100644 --- /dev/null +++ b/src/app/Meet/Service.php @@ -0,0 +1,86 @@ + 1 && $roomName) { + $index = abs(intval(hash('crc32b', $roomName), 16) % $count); + } + + return $urls[$index]; + } + + /** + * Creates HTTP client for connection to the Meet server + * + * @param ?string $roomName Room name + * + * @return HTTP client instance + */ + public static function clientForRoom($roomName = null) + { + $url = self::selectMeetServer($roomName); + + return Http::withSlowLog() + ->withOptions([ + 'verify' => \config('meet.api_verify_tls'), + ]) + ->withHeaders([ + 'X-Auth-Token' => \config('meet.api_token'), + ]) + ->baseUrl($url) + ->timeout(10) + ->connectTimeout(10); + } + + /** + * Creates HTTP client for connection to the Meet server. + * Server location can be provided, otherwise first server on the list is used. + * + * @param ?string $baseUrl Server location + * + * @return HTTP client instance + */ + public static function client($baseUrl = null) + { + if (empty($baseUrl)) { + $baseUrl = self::selectMeetServer(); + } + + return Http::withSlowLog() + ->withOptions([ + 'verify' => \config('meet.api_verify_tls'), + ]) + ->withHeaders([ + 'X-Auth-Token' => \config('meet.api_token'), + ]) + ->baseUrl($baseUrl) + ->timeout(10) + ->connectTimeout(10); + } +} diff --git a/src/app/Providers/AppServiceProvider.php b/src/app/Providers/AppServiceProvider.php --- a/src/app/Providers/AppServiceProvider.php +++ b/src/app/Providers/AppServiceProvider.php @@ -4,6 +4,7 @@ use Illuminate\Database\Query\Builder; use Illuminate\Support\Facades\Blade; +use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Schema; use Illuminate\Support\ServiceProvider; use Laravel\Passport\Passport; @@ -149,6 +150,19 @@ } ); + Http::macro('withSlowLog', function () { + return Http::withOptions([ + 'on_stats' => function (\GuzzleHttp\TransferStats $stats) { + $threshold = \config('logging.slow_log'); + if ($threshold && ($sec = $stats->getTransferTime()) > $threshold) { + $url = $stats->getEffectiveUri(); + $method = $stats->getRequest()->getMethod(); + \Log::warning(sprintf("[STATS] %s %s: %.4f sec.", $method, $url, $sec)); + } + }, + ]); + }); + $this->applyOverrideConfig(); } }