feat: WebRTC MVP to Blax standard (namespace, README, tests, scaffolding)
- Rename namespace BlaxSoftware\LaravelWebRtc -> Blax\WebRtc (house standard) +
update kernel imports to Blax\ReactPhpKernel
- README rewritten to the Blax OSS package principles: OSS banner, title+badges,
emoji feature list, quick start, wire shape, config, architecture, star history
- Add PHPUnit suite (8 tests / 18 assertions, green): SignalingHandler routing
(offer/ice/record/connect/bridge/close/error paths via a fake engine) +
NullMediaEngine behaviour
- Add pint.json (laravel preset, applied), composer scripts, .gitattributes,
test.sh (nix), CHANGELOG
- Verified end-to-end: composer install resolves blax-software/reactphp-kernel
from Forgejo VCS and the suite runs green on it
rel learn-atc #1055 #1051 #1019
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 11:28:49 +00:00
[](https://github.com/blax-software)
2026-07-07 11:07:59 +00:00
feat: WebRTC MVP to Blax standard (namespace, README, tests, scaffolding)
- Rename namespace BlaxSoftware\LaravelWebRtc -> Blax\WebRtc (house standard) +
update kernel imports to Blax\ReactPhpKernel
- README rewritten to the Blax OSS package principles: OSS banner, title+badges,
emoji feature list, quick start, wire shape, config, architecture, star history
- Add PHPUnit suite (8 tests / 18 assertions, green): SignalingHandler routing
(offer/ice/record/connect/bridge/close/error paths via a fake engine) +
NullMediaEngine behaviour
- Add pint.json (laravel preset, applied), composer scripts, .gitattributes,
test.sh (nix), CHANGELOG
- Verified end-to-end: composer install resolves blax-software/reactphp-kernel
from Forgejo VCS and the suite runs green on it
rel learn-atc #1055 #1051 #1019
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 11:28:49 +00:00
# Laravel WebRTC
2026-07-07 11:07:59 +00:00
feat: WebRTC MVP to Blax standard (namespace, README, tests, scaffolding)
- Rename namespace BlaxSoftware\LaravelWebRtc -> Blax\WebRtc (house standard) +
update kernel imports to Blax\ReactPhpKernel
- README rewritten to the Blax OSS package principles: OSS banner, title+badges,
emoji feature list, quick start, wire shape, config, architecture, star history
- Add PHPUnit suite (8 tests / 18 assertions, green): SignalingHandler routing
(offer/ice/record/connect/bridge/close/error paths via a fake engine) +
NullMediaEngine behaviour
- Add pint.json (laravel preset, applied), composer scripts, .gitattributes,
test.sh (nix), CHANGELOG
- Verified end-to-end: composer install resolves blax-software/reactphp-kernel
from Forgejo VCS and the suite runs green on it
rel learn-atc #1055 #1051 #1019
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 11:28:49 +00:00
[](https://php.net)
[](https://laravel.com)
[](https://github.com/blax-software/reactphp-kernel)
2026-07-08 06:35:02 +00:00
[](#testing)
[](#testing)
feat: WebRTC MVP to Blax standard (namespace, README, tests, scaffolding)
- Rename namespace BlaxSoftware\LaravelWebRtc -> Blax\WebRtc (house standard) +
update kernel imports to Blax\ReactPhpKernel
- README rewritten to the Blax OSS package principles: OSS banner, title+badges,
emoji feature list, quick start, wire shape, config, architecture, star history
- Add PHPUnit suite (8 tests / 18 assertions, green): SignalingHandler routing
(offer/ice/record/connect/bridge/close/error paths via a fake engine) +
NullMediaEngine behaviour
- Add pint.json (laravel preset, applied), composer scripts, .gitattributes,
test.sh (nix), CHANGELOG
- Verified end-to-end: composer install resolves blax-software/reactphp-kernel
from Forgejo VCS and the suite runs green on it
rel learn-atc #1055 #1051 #1019
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 11:28:49 +00:00
[](LICENSE)
2026-07-07 11:07:59 +00:00
2026-07-08 06:35:02 +00:00
WebRTC for Laravel on the shared [`reactphp-kernel` ](https://github.com/blax-software/reactphp-kernel ) backbone. A **WebSocket signaling relay** connects browsers for **peer-to-peer calls today** (no server-side media needed); when you need the server *in* the media path — recording, AI bridging, an SFU — a pluggable **media engine** (a Rust `str0m` core via `ext-php-rs` ) takes over.
2026-07-07 11:07:59 +00:00
feat: WebRTC MVP to Blax standard (namespace, README, tests, scaffolding)
- Rename namespace BlaxSoftware\LaravelWebRtc -> Blax\WebRtc (house standard) +
update kernel imports to Blax\ReactPhpKernel
- README rewritten to the Blax OSS package principles: OSS banner, title+badges,
emoji feature list, quick start, wire shape, config, architecture, star history
- Add PHPUnit suite (8 tests / 18 assertions, green): SignalingHandler routing
(offer/ice/record/connect/bridge/close/error paths via a fake engine) +
NullMediaEngine behaviour
- Add pint.json (laravel preset, applied), composer scripts, .gitattributes,
test.sh (nix), CHANGELOG
- Verified end-to-end: composer install resolves blax-software/reactphp-kernel
from Forgejo VCS and the suite runs green on it
rel learn-atc #1055 #1051 #1019
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 11:28:49 +00:00
## Features
2026-07-07 11:07:59 +00:00
2026-07-08 06:35:02 +00:00
- 📞 **Browser-to-browser calls, working today** — two browsers `join` a room and the server relays their SDP/ICE so they connect **peer-to-peer** ; the audio never touches the server, so no media engine is required
- 👥 **Rooms & mesh signaling** — peer discovery on join, `peer-joined` / `peer-left` notifications, targeted `relay` , and room `broadcast`
- 🧩 **On the shared kernel** — runs on `reactphp-kernel` over the [`laravel-ws` ](https://github.com/blax-software/laravel-ws ) WebSocket transport; one process, one loop, alongside your other realtime servers
- 🎙️ **Server-side media, when you need it** — a pluggable `MediaEngine` terminates media for **recording / intercept** , **AI-realtime bridging** , and **SFU** group calls
- 🤖 **AI realtime, provider hidden** — bridge a caller to an external model (e.g. OpenAI Realtime) server-side; the browser only ever talks to *you* , and the model is a config swap
- 🔌 **Pluggable engine** — `NullMediaEngine` (signaling-only) now; `Str0mMediaEngine` (Rust `str0m` via `ext-php-rs` , shipped in `rust/` ) for real server-terminated media
2026-07-07 11:07:59 +00:00
feat: WebRTC MVP to Blax standard (namespace, README, tests, scaffolding)
- Rename namespace BlaxSoftware\LaravelWebRtc -> Blax\WebRtc (house standard) +
update kernel imports to Blax\ReactPhpKernel
- README rewritten to the Blax OSS package principles: OSS banner, title+badges,
emoji feature list, quick start, wire shape, config, architecture, star history
- Add PHPUnit suite (8 tests / 18 assertions, green): SignalingHandler routing
(offer/ice/record/connect/bridge/close/error paths via a fake engine) +
NullMediaEngine behaviour
- Add pint.json (laravel preset, applied), composer scripts, .gitattributes,
test.sh (nix), CHANGELOG
- Verified end-to-end: composer install resolves blax-software/reactphp-kernel
from Forgejo VCS and the suite runs green on it
rel learn-atc #1055 #1051 #1019
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 11:28:49 +00:00
## Installation
2026-07-07 11:07:59 +00:00
```bash
feat: WebRTC MVP to Blax standard (namespace, README, tests, scaffolding)
- Rename namespace BlaxSoftware\LaravelWebRtc -> Blax\WebRtc (house standard) +
update kernel imports to Blax\ReactPhpKernel
- README rewritten to the Blax OSS package principles: OSS banner, title+badges,
emoji feature list, quick start, wire shape, config, architecture, star history
- Add PHPUnit suite (8 tests / 18 assertions, green): SignalingHandler routing
(offer/ice/record/connect/bridge/close/error paths via a fake engine) +
NullMediaEngine behaviour
- Add pint.json (laravel preset, applied), composer scripts, .gitattributes,
test.sh (nix), CHANGELOG
- Verified end-to-end: composer install resolves blax-software/reactphp-kernel
from Forgejo VCS and the suite runs green on it
rel learn-atc #1055 #1051 #1019
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 11:28:49 +00:00
composer require blax-software/laravel-webrtc
php artisan vendor:publish --tag="webrtc-config"
2026-07-07 11:07:59 +00:00
```
2026-07-08 06:35:02 +00:00
It depends on [`blax-software/reactphp-kernel` ](https://github.com/blax-software/reactphp-kernel ) + [`blax-software/laravel-ws` ](https://github.com/blax-software/laravel-ws ), resolved from git.blax.at via the `repositories` entry in `composer.json` .
feat: WebRTC MVP to Blax standard (namespace, README, tests, scaffolding)
- Rename namespace BlaxSoftware\LaravelWebRtc -> Blax\WebRtc (house standard) +
update kernel imports to Blax\ReactPhpKernel
- README rewritten to the Blax OSS package principles: OSS banner, title+badges,
emoji feature list, quick start, wire shape, config, architecture, star history
- Add PHPUnit suite (8 tests / 18 assertions, green): SignalingHandler routing
(offer/ice/record/connect/bridge/close/error paths via a fake engine) +
NullMediaEngine behaviour
- Add pint.json (laravel preset, applied), composer scripts, .gitattributes,
test.sh (nix), CHANGELOG
- Verified end-to-end: composer install resolves blax-software/reactphp-kernel
from Forgejo VCS and the suite runs green on it
rel learn-atc #1055 #1051 #1019
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 11:28:49 +00:00
## Quick Start
2026-07-07 11:07:59 +00:00
2026-07-08 06:35:02 +00:00
Run the signaling relay (browsers connect here):
2026-07-07 11:07:59 +00:00
```bash
2026-07-08 06:35:02 +00:00
php artisan webrtc:serve # ws://127.0.0.1:8090 by default
2026-07-07 11:07:59 +00:00
```
2026-07-08 06:35:02 +00:00
That's all a **peer-to-peer call** needs — the server only relays signaling; the browsers exchange audio directly:
```js
const ws = new WebSocket('ws://127.0.0.1:8090')
const pc = new RTCPeerConnection()
let peer
ws.onmessage = async ({ data }) => {
const m = JSON.parse(data)
if (m.type === 'welcome') ws.send(JSON.stringify({ type: 'join', room: 'lobby' }))
if (m.type === 'joined') m.peers.forEach(p => (peer = p, call(p))) // someone's already here → call them
if (m.type === 'peer-joined') peer = m.peer // they'll send us an offer
if (m.type === 'relay') { // SDP / ICE from the other browser
peer = m.from
if (m.data.sdp) { await pc.setRemoteDescription(m.data); if (m.data.type === 'offer') answer() }
if (m.data.candidate) await pc.addIceCandidate(m.data)
}
}
pc.onicecandidate = e => e.candidate & & ws.send(JSON.stringify({ type: 'relay', to: peer, data: e.candidate }))
pc.ontrack = e => audioEl.srcObject = e.streams[0]
const send = (data) => ws.send(JSON.stringify({ type: 'relay', to: peer, data }))
async function call() { const o = await pc.createOffer(); await pc.setLocalDescription(o); send(o) }
async function answer() { const a = await pc.createAnswer(); await pc.setLocalDescription(a); send(a) }
feat: WebRTC MVP to Blax standard (namespace, README, tests, scaffolding)
- Rename namespace BlaxSoftware\LaravelWebRtc -> Blax\WebRtc (house standard) +
update kernel imports to Blax\ReactPhpKernel
- README rewritten to the Blax OSS package principles: OSS banner, title+badges,
emoji feature list, quick start, wire shape, config, architecture, star history
- Add PHPUnit suite (8 tests / 18 assertions, green): SignalingHandler routing
(offer/ice/record/connect/bridge/close/error paths via a fake engine) +
NullMediaEngine behaviour
- Add pint.json (laravel preset, applied), composer scripts, .gitattributes,
test.sh (nix), CHANGELOG
- Verified end-to-end: composer install resolves blax-software/reactphp-kernel
from Forgejo VCS and the suite runs green on it
rel learn-atc #1055 #1051 #1019
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 11:28:49 +00:00
```
2026-07-08 06:35:02 +00:00
### Relay protocol (JSON over WebSocket)
2026-07-07 11:07:59 +00:00
```jsonc
2026-07-08 06:35:02 +00:00
← { "type": "welcome", "peer": "< yourId > " } // on connect
→ { "type": "join", "room": "lobby" }
← { "type": "joined", "room": "lobby", "peers": ["< id > ", ...] } // who's already here
← { "type": "peer-joined", "room": "lobby", "peer": "< id > " } // sent to the others
→ { "type": "relay", "to": "< peerId > ", "data": { ...sdp | candidate... } }
← { "type": "relay", "from": "< peerId > ", "data": { ... } } // delivered to the target
→ { "type": "broadcast", "data": { ... } } // to the rest of your room
→ { "type": "leave" } ← { "type": "left" } / others get { "type": "peer-left", "peer" }
```
### Server-terminated media (recording / AI bridge / SFU)
When the server must be *in* the media path, configure a `MediaEngine` . `NullMediaEngine` (default) is signaling-only; `Str0mMediaEngine` is backed by a Rust `str0m` core via `ext-php-rs` (see [`rust/README.md` ](rust/README.md )):
```dotenv
WEBRTC_MEDIA_ENGINE="Blax\WebRtc\Media\Str0mMediaEngine"
2026-07-07 11:07:59 +00:00
```
2026-07-08 06:35:02 +00:00
The engine-backed path uses `Signaling\SignalingHandler` (offer/ice/record/connect/bridge/close) + `Server\SignalingServer` ; it's independent of the browser relay above and shares the same `RoomManager` .
feat: WebRTC MVP to Blax standard (namespace, README, tests, scaffolding)
- Rename namespace BlaxSoftware\LaravelWebRtc -> Blax\WebRtc (house standard) +
update kernel imports to Blax\ReactPhpKernel
- README rewritten to the Blax OSS package principles: OSS banner, title+badges,
emoji feature list, quick start, wire shape, config, architecture, star history
- Add PHPUnit suite (8 tests / 18 assertions, green): SignalingHandler routing
(offer/ice/record/connect/bridge/close/error paths via a fake engine) +
NullMediaEngine behaviour
- Add pint.json (laravel preset, applied), composer scripts, .gitattributes,
test.sh (nix), CHANGELOG
- Verified end-to-end: composer install resolves blax-software/reactphp-kernel
from Forgejo VCS and the suite runs green on it
rel learn-atc #1055 #1051 #1019
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 11:28:49 +00:00
## Configuration
`config/webrtc.php` covers the signaling bind (`host`/`port`/`tls`), the `media_engine` binding, `recording` disk/path, advertised `ice_servers` , and the external `bridge` (e.g. OpenAI model + key). Swapping the realtime model — or the whole provider — is a server-side config change the browser never sees.
## Status
2026-07-08 06:35:02 +00:00
**Working MVP.** Browser-to-browser (mesh) calls work today via the WebSocket signaling relay — no server-side media required. Rooms, peer discovery, targeted relay and broadcast are tested, including a real WebSocket round-trip. Server-terminated media (recording, AI bridge, SFU) is the pluggable `MediaEngine` ; the real one (`Str0mMediaEngine` + `rust/` ) is the next build.
feat: WebRTC MVP to Blax standard (namespace, README, tests, scaffolding)
- Rename namespace BlaxSoftware\LaravelWebRtc -> Blax\WebRtc (house standard) +
update kernel imports to Blax\ReactPhpKernel
- README rewritten to the Blax OSS package principles: OSS banner, title+badges,
emoji feature list, quick start, wire shape, config, architecture, star history
- Add PHPUnit suite (8 tests / 18 assertions, green): SignalingHandler routing
(offer/ice/record/connect/bridge/close/error paths via a fake engine) +
NullMediaEngine behaviour
- Add pint.json (laravel preset, applied), composer scripts, .gitattributes,
test.sh (nix), CHANGELOG
- Verified end-to-end: composer install resolves blax-software/reactphp-kernel
from Forgejo VCS and the suite runs green on it
rel learn-atc #1055 #1051 #1019
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 11:28:49 +00:00
## Architecture
```
2026-07-08 06:35:02 +00:00
reactphp-kernel shared backbone (loop, IPC, signals)
├─ laravel-ws WebSocket transport (RFC6455)
└─ laravel-webrtc (this)
├─ RelaySignalingHandler browser P2P calls (no media engine needed)
└─ MediaEngine (optional) server-terminated media
└─ Str0mMediaEngine Rust/str0m via ext-php-rs (rust/)
feat: WebRTC MVP to Blax standard (namespace, README, tests, scaffolding)
- Rename namespace BlaxSoftware\LaravelWebRtc -> Blax\WebRtc (house standard) +
update kernel imports to Blax\ReactPhpKernel
- README rewritten to the Blax OSS package principles: OSS banner, title+badges,
emoji feature list, quick start, wire shape, config, architecture, star history
- Add PHPUnit suite (8 tests / 18 assertions, green): SignalingHandler routing
(offer/ice/record/connect/bridge/close/error paths via a fake engine) +
NullMediaEngine behaviour
- Add pint.json (laravel preset, applied), composer scripts, .gitattributes,
test.sh (nix), CHANGELOG
- Verified end-to-end: composer install resolves blax-software/reactphp-kernel
from Forgejo VCS and the suite runs green on it
rel learn-atc #1055 #1051 #1019
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 11:28:49 +00:00
```
## Testing
```bash
composer install
composer test
```
2026-07-08 06:35:02 +00:00
The relay + signaling routers and engines are unit-tested with fakes; a real WebSocket round-trip proves the relay over `laravel-ws` , and a raw-socket test drives the engine signaling server — no browser or external services required.
2026-07-07 11:07:59 +00:00
## License
feat: WebRTC MVP to Blax standard (namespace, README, tests, scaffolding)
- Rename namespace BlaxSoftware\LaravelWebRtc -> Blax\WebRtc (house standard) +
update kernel imports to Blax\ReactPhpKernel
- README rewritten to the Blax OSS package principles: OSS banner, title+badges,
emoji feature list, quick start, wire shape, config, architecture, star history
- Add PHPUnit suite (8 tests / 18 assertions, green): SignalingHandler routing
(offer/ice/record/connect/bridge/close/error paths via a fake engine) +
NullMediaEngine behaviour
- Add pint.json (laravel preset, applied), composer scripts, .gitattributes,
test.sh (nix), CHANGELOG
- Verified end-to-end: composer install resolves blax-software/reactphp-kernel
from Forgejo VCS and the suite runs green on it
rel learn-atc #1055 #1051 #1019
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 11:28:49 +00:00
MIT. See [LICENSE ](LICENSE ).
## Star History
< a href = "https://www.star-history.com/?repos=blax-software%2Flaravel-webrtc&type=date&legend=top-left" >
< picture >
< source media = "(prefers-color-scheme: dark)" srcset = "https://api.star-history.com/chart?repos=blax-software/laravel-webrtc&type=date&theme=dark&legend=top-left" / >
< source media = "(prefers-color-scheme: light)" srcset = "https://api.star-history.com/chart?repos=blax-software/laravel-webrtc&type=date&legend=top-left" / >
< img alt = "Star History Chart" src = "https://api.star-history.com/chart?repos=blax-software/laravel-webrtc&type=date&legend=top-left" / >
< / picture >
< / a >