Read from the package's own PHP files at the commit d480fdb07983: its namespaces, classes, interfaces and enums, their public constants, properties and methods with their PHPDoc, and the options its factories take. Nothing of it is run.
ApiclassWhat the direct gateway's actions work with - there is no provider to call: the handshake's rules on the application's store, the relay's temporary credentials, and the engine's file.
2 methods · 2 properties · 1 constant
DirectGatewayFactoryclassFrom browser to browser: two people, their media encrypted end to end (WebRTC, DTLS-SRTP), nobody in between, nothing recorded. The application relays the handshake over HTTP and keeps it in the store it gives; when a network forbids the direct way the media go through the application's own TURN relay - still encrypted, never through a third party.
10 options · 2 methods
InMemorySignalStoreclassThe handshake kept in this PHP process: for tests, a harness, a long-running server. Between two HTTP requests of an ordinary application it forgets everything - that one implements SignalStoreInterface on what it stores with.
3 methods
SignalclassOne message of the handshake, from one participant of a room to the other: a hello, an offer, an answer, an ICE candidate, a goodbye.
3 methods · 5 properties
SignalStoreInterfaceinterfaceWhere the handshake waits between the request that posts a message and the request that reads it: a table, a cache, a file - the application's choice, and the only thing this package needs from it. A room is named by the meeting's reference, a participant by their opaque identifier.
3 methods
SignalingclassThe WebRTC handshake relayed over plain HTTP: one side posts its hello, its offer, its answer, its ICE candidates; the other asks, every second while the call is being set up, for what came after the last message it read. No WebSocket server to run; the media themselves never come here.
5 methods · 8 constants
TurnCredentialsclassTemporary TURN credentials, the "TURN REST API" coturn checks with use-auth-secret: the username is "<expiry>:<who>", the password the base64 HMAC-SHA1 of that username with the shared secret. Nothing to store, nothing to revoke: they lapse by themselves (the ttl).
10 methods
CloseActionclassThe room's handshake goes: nothing of the call is kept.
3 methods
FetchActionclassThe room read from its handshake, the only trace there is: who said something and has not left since, and whether the two are connected (LIVE). A closed room has no trace: a meeting given as ENDED, or whose end is past, stays ENDED. Who each participant is - their role, their name - the application knows; here they are identifiers.
3 methods
JoinActionclassThe engine and what it starts with: the participant's side of the handshake (the host offers, the guest answers) and the ICE servers - the relay with credentials made for this participant, valid for the ttl.
3 methods
OpenActionclassNothing to open anywhere: the room is the meeting's own key, under which its handshake will be kept. The same key, the same room.
2 methods
InvalidSignalExceptionclassWhat a participant sent is not a message of the handshake: an unknown type, a document that is not JSON or is too large.
Omnimeet\Direct
Api class
final class Api Api.php:10
What the direct gateway's actions work with - there is no provider to call: the handshake's rules on the application's store, the relay's temporary credentials, and the engine's file.
const ENGINE = 'direct'public readonly Signaling $signalingpublic readonly TurnCredentials $turn
Api::__construct()
public function __construct(public readonly Signaling $signaling, public readonly TurnCredentials $turn)Api::script()
public static function script(): stringThe JavaScript engine, as the package ships it: the application serves this file.
DirectGatewayFactory class
final class DirectGatewayFactory extends GatewayFactory DirectGatewayFactory.php:32
From browser to browser: two people, their media encrypted end to end (WebRTC, DTLS-SRTP), nobody in between, nothing recorded. The application relays the handshake over HTTP and keeps it in the store it gives; when a network forbids the direct way the media go through the application's own TURN relay - still encrypted, never through a third party.
options: turn_secret: '%env(TURN_SECRET)%' # coturn's static-auth-secret: the temporary credentials are signed with it turn_urls: ['turn:turn.example.org:3478?transport=udp', 'turn:turn.example.org:3478?transport=tcp'] stun_urls: [] # none by default: no third party is asked where the browser is turn_ttl: 3600 # seconds the credentials last
No option is required: without a relay the two browsers connect directly, or not at all. No callbacks: there is no provider to send any (notify() is not supported).
Options
| Option | Default | |
|---|---|---|
omnimeet.capabilities | new Capabilities(maxParticipants: 2, thirdParty: false, endToEnd: true, recording: false, screenSharing: true, chat: true, tokens: false, access: [AccessKind… | |
turn_secret | null | |
turn_urls | [] | |
stun_urls | [] | |
turn_ttl | 3600 | |
omnimeet.api | fn(Config $c) => new Api($this->signaling(), new TurnCredentials(null === $c['turn_secret'] || '' === $c['turn_secret'] ? null : (string) $c['turn_secret'], … | |
omnimeet.action.open | new OpenAction() | |
omnimeet.action.join | new JoinAction() | |
omnimeet.action.close | new CloseAction() | |
omnimeet.action.fetch | new FetchAction() |
DirectGatewayFactory::__construct()
public function __construct(?SignalStoreInterface $signals = null)$signalswhere the handshake waits; in this process's memory when none is given
DirectGatewayFactory::signaling()
public function signaling(): SignalingThe handshake's rules on this factory's store: what the application's two endpoints (post, poll) call.
InMemorySignalStore class
final class InMemorySignalStore implements SignalStoreInterface InMemorySignalStore.php:11
The handshake kept in this PHP process: for tests, a harness, a long-running server. Between two HTTP requests of an ordinary application it forgets everything - that one implements SignalStoreInterface on what it stores with.
InMemorySignalStore::append()
public function append(string $room, string $sender, string $type, string $payload): intInMemorySignalStore::read()
public function read(string $room, int $after = 0, ?string $except = null, int $limit = 200): arrayInMemorySignalStore::purge()
public function purge(string $room): intSignal class
final readonly class Signal Signal.php:9
One message of the handshake, from one participant of a room to the other: a hello, an offer, an answer, an ICE candidate, a goodbye.
public int $idits number: greater than every one before it in the room
public string $roompublic string $senderthe participant's opaque identifier (Omnimeet\Model\Participant::$id)
public string $typepublic string $payloada JSON document: the session description, the candidate, or null
Signal::__construct()
public function __construct(public int $id, public string $room, public string $sender, public string $type, public string $payload = 'null')$idits number: greater than every one before it in the room
$senderthe participant's opaque identifier (Omnimeet\Model\Participant::$id)
$payloada JSON document: the session description, the candidate, or null
Signal::connects()
public function connects(): boolAn answer given: from here on the two browsers talk to each other.
Signal::toArray()
public function toArray(): array- Returns
what the other side's page is given
SignalStoreInterface interface
interface SignalStoreInterface SignalStoreInterface.php:14
Where the handshake waits between the request that posts a message and the request that reads it: a table, a cache, a file - the application's choice, and the only thing this package needs from it. A room is named by the meeting's reference, a participant by their opaque identifier.
Nothing of the call itself ever comes here: a few kilobytes per call, gone when the meeting closes.
SignalStoreInterface::append()
public function append(string $room, string $sender, string $type, string $payload): int- Returns
the number given to the message: greater than every one before it in the room
SignalStoreInterface::read()
public function read(string $room, int $after = 0, ?string $except = null, int $limit = 200): arrayThe room's messages numbered above $after, oldest first.
$exceptleave out what this participant sent: nobody hears themselves
SignalStoreInterface::purge()
public function purge(string $room): int- Returns
how many messages went
Signaling class
final class Signaling Signaling.php:26
The WebRTC handshake relayed over plain HTTP: one side posts its hello, its offer, its answer, its ICE candidates; the other asks, every second while the call is being set up, for what came after the last message it read. No WebSocket server to run; the media themselves never come here.
The rules: - five messages, and no other: hello, offer, answer, candidate, bye; - a message carries one JSON document of at most MAX_PAYLOAD bytes; - a participant reads what the other sent, never their own, in the order it was sent, from the number they give (PAGE at most at once); - an answer means the two are connected; a hello or a bye, that the handshake starts again or stopped; - closing a room purges it: nothing of a call outlives it.
Who may post in a room - its two participants, while it is open - is the application's to check before it calls send().
const HELLO = 'hello'const OFFER = 'offer'const ANSWER = 'answer'const CANDIDATE = 'candidate'const BYE = 'bye'const TYPES = [self::OFFER, self::ANSWER, self::CANDIDATE, self::BYE, self::HELLO]const MAX_PAYLOAD = 65536const PAGE = 200
Signaling::__construct()
public function __construct(readonly SignalStoreInterface $store)Signaling::send()
public function send(string $room, string $sender, string $type, string $payload = 'null'): Signal$payloada JSON document ("null" for a hello or a bye)
- Throws
InvalidSignalException
Signaling::receive()
public function receive(string $room, string $recipient, int $after = 0): arrayWhat the other side sent after $after.
Signaling::purge()
public function purge(string $room): intThe room closes: its handshake goes.
Signaling::state()
public function state(string $room): arrayWhere the room stands, read from its handshake alone: who said something and has not said goodbye since, and whether an answer was given since the handshake last started.
TurnCredentials class
class TurnCredentials TurnCredentials.php:13
Temporary TURN credentials, the "TURN REST API" coturn checks with use-auth-secret: the username is "<expiry>:<who>", the password the base64 HMAC-SHA1 of that username with the shared secret. Nothing to store, nothing to revoke: they lapse by themselves (the ttl).
TurnCredentials::__construct()
public function __construct(?string $secret = null, array $turnUrls = [], array $stunUrls = [], readonly int $ttl = 3600)TurnCredentials::fromOptions()
public static function fromOptions(array $options): staticFrom a direct gateway's options: turn_secret, turn_urls, stun_urls, turn_ttl.
TurnCredentials::urls()
public static function urls(array $urls): arrayA list given as one environment variable arrives as a single comma-separated string: split here, at run time.
TurnCredentials::turnUrls()
public function turnUrls(): arrayTurnCredentials::stunUrls()
public function stunUrls(): arrayTurnCredentials::ttl()
public function ttl(): intTurnCredentials::isConfigured()
public function isConfigured(): boolTurnCredentials::issue()
public function issue(string $who, ?int $now = null): arrayTurnCredentials::verify()
public function verify(string $username, string $credential, ?int $now = null): boolWhether credentials were made with this secret and are still valid.
TurnCredentials::iceServers()
public function iceServers(string $who, ?int $now = null): arrayRTCPeerConnection's iceServers: the TURN relay with fresh credentials, the STUN servers if any (none by default: no third party is asked where the browser is).
Omnimeet\Direct\Action
CloseAction class
final class CloseAction implements ActionInterface, ApiAwareInterface CloseAction.php:14
The room's handshake goes: nothing of the call is kept.
CloseAction::__construct()
public function __construct()CloseAction::supports()
public function supports(Request $request): boolCloseAction::execute()
public function execute(Request $request): voidFetchAction class
final class FetchAction implements ActionInterface, ApiAwareInterface FetchAction.php:21
The room read from its handshake, the only trace there is: who said something and has not left since, and whether the two are connected (LIVE). A closed room has no trace: a meeting given as ENDED, or whose end is past, stays ENDED. Who each participant is - their role, their name - the application knows; here they are identifiers.
FetchAction::__construct()
public function __construct()FetchAction::supports()
public function supports(Request $request): boolFetchAction::execute()
public function execute(Request $request): voidJoinAction class
final class JoinAction implements ActionInterface, ApiAwareInterface JoinAction.php:20
The engine and what it starts with: the participant's side of the handshake (the host offers, the guest answers) and the ICE servers - the relay with credentials made for this participant, valid for the ttl.
Where the handshake is posted and read is the application's: its own addresses, which it adds when it renders the page.
JoinAction::__construct()
public function __construct()JoinAction::supports()
public function supports(Request $request): boolJoinAction::execute()
public function execute(Request $request): voidOpenAction class
final class OpenAction implements ActionInterface OpenAction.php:14
Nothing to open anywhere: the room is the meeting's own key, under which its handshake will be kept. The same key, the same room.
OpenAction::supports()
public function supports(Request $request): boolOpenAction::execute()
public function execute(Request $request): voidOmnimeet\Direct\Exception
InvalidSignalException class
final class InvalidSignalException extends InvalidArgumentException implements OmnimeetException InvalidSignalException.php:8
What a participant sent is not a message of the handshake: an unknown type, a document that is not JSON or is too large.