mirror of
git://f0xx.org/ac/ac-ms-sfu-signaling
synced 2026-07-29 07:38:35 +03:00
sfu-signaling: real Janus signaling service implementation
- JanusClient.php: HTTP REST client for Janus Gateway API - SfuRoomRepository.php: room + participant + stats persistence - bootstrap.php: PDO, auth, Janus client factory - public/index.php: front-controller routing - public/health.php: Janus online check - public/api/rooms.php: list/create/destroy rooms - public/api/join.php: SDP offer relay → Janus VideoRoom - public/api/stats.php: bitrate/packet-loss analytics ingest - public/dashboard.php: SFU rooms UI (common BE dark-theme styles) Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
119
src/bootstrap.php
Normal file
119
src/bootstrap.php
Normal file
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* SFU signaling bootstrap — minimal standalone setup.
|
||||
* Reuses the composed BE database and session if available,
|
||||
* otherwise falls back to own PDO from environment.
|
||||
*/
|
||||
|
||||
define('SFU_ROOT', dirname(__DIR__));
|
||||
|
||||
/* ── autoloader ───────────────────────────────────────────────────── */
|
||||
spl_autoload_register(static function (string $class): void {
|
||||
$prefix = 'AndroidCast\\Sfu\\';
|
||||
if (str_starts_with($class, $prefix)) {
|
||||
$rel = str_replace('\\', '/', substr($class, strlen($prefix)));
|
||||
$file = SFU_ROOT . '/src/' . $rel . '.php';
|
||||
if (is_file($file)) {
|
||||
require_once $file;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/* ── configuration ────────────────────────────────────────────────── */
|
||||
|
||||
function sfuConfig(string $key, mixed $default = null): mixed
|
||||
{
|
||||
static $cfg = null;
|
||||
if ($cfg === null) {
|
||||
$cfgFile = SFU_ROOT . '/config/config.php';
|
||||
$cfg = is_file($cfgFile) ? (require $cfgFile) : [];
|
||||
/* Env overrides */
|
||||
if (getenv('JANUS_URL') !== false) {
|
||||
$cfg['janus_url'] = getenv('JANUS_URL');
|
||||
}
|
||||
if (getenv('DB_DSN') !== false) {
|
||||
$cfg['db_dsn'] = getenv('DB_DSN');
|
||||
}
|
||||
}
|
||||
return $cfg[$key] ?? $default;
|
||||
}
|
||||
|
||||
/* ── PDO ────────────────────────────────────────────────────────────── */
|
||||
|
||||
function sfuPdo(): \PDO
|
||||
{
|
||||
static $pdo = null;
|
||||
if ($pdo === null) {
|
||||
/* Prefer composed BE PDO if already bootstrapped */
|
||||
$composedBe = '/var/www/ac/composed/backend/src/bootstrap.php';
|
||||
if (is_file($composedBe)) {
|
||||
require_once $composedBe;
|
||||
if (function_exists('db')) {
|
||||
$pdo = db();
|
||||
return $pdo;
|
||||
}
|
||||
}
|
||||
/* Fall back to own DSN */
|
||||
$dsn = sfuConfig('db_dsn', 'mysql:host=cast01;dbname=androidcast;charset=utf8mb4');
|
||||
$user = sfuConfig('db_user', 'androidcast');
|
||||
$pass = sfuConfig('db_pass', '');
|
||||
$pdo = new \PDO($dsn, $user, $pass, [
|
||||
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
|
||||
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
|
||||
]);
|
||||
}
|
||||
return $pdo;
|
||||
}
|
||||
|
||||
/* ── Janus client ────────────────────────────────────────────────── */
|
||||
|
||||
function janusClient(): \AndroidCast\Sfu\JanusClient
|
||||
{
|
||||
static $client = null;
|
||||
if ($client === null) {
|
||||
$url = sfuConfig('janus_url', 'http://10.7.16.237:8088/janus');
|
||||
$client = new \AndroidCast\Sfu\JanusClient($url);
|
||||
}
|
||||
return $client;
|
||||
}
|
||||
|
||||
/* ── Auth helper ─────────────────────────────────────────────────── */
|
||||
|
||||
function sfuRequireAuth(): array
|
||||
{
|
||||
/* Try composed BE session */
|
||||
$composedBe = '/var/www/ac/composed/backend/src/bootstrap.php';
|
||||
if (is_file($composedBe)) {
|
||||
require_once $composedBe;
|
||||
if (function_exists('requireAuth')) {
|
||||
return requireAuth();
|
||||
}
|
||||
}
|
||||
/* Minimal cookie/bearer check */
|
||||
session_start();
|
||||
if (empty($_SESSION['user_id'])) {
|
||||
http_response_code(401);
|
||||
echo json_encode(['ok' => false, 'error' => 'unauthorized']);
|
||||
exit;
|
||||
}
|
||||
return ['id' => (int) $_SESSION['user_id'], 'email' => $_SESSION['email'] ?? ''];
|
||||
}
|
||||
|
||||
/* ── JSON helpers ────────────────────────────────────────────────── */
|
||||
|
||||
function sfuJsonOk(array $data = []): void
|
||||
{
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
echo json_encode(['ok' => true] + $data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
}
|
||||
|
||||
function sfuJsonErr(string $message, int $code = 400): void
|
||||
{
|
||||
http_response_code($code);
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
echo json_encode(['ok' => false, 'error' => $message], JSON_UNESCAPED_SLASHES);
|
||||
exit;
|
||||
}
|
||||
Reference in New Issue
Block a user