reactphp-kernel/README.md

118 lines
4.9 KiB
Markdown

[![Blax Software OSS](https://raw.githubusercontent.com/blax-software/laravel-workkit/master/art/oss-initiative-banner.svg)](https://github.com/blax-software)
# ReactPHP Kernel
[![PHP Version](https://img.shields.io/badge/php-%5E8.1-blue?style=flat-square)](https://php.net)
[![Built on ReactPHP](https://img.shields.io/badge/built%20on-ReactPHP-4b275f?style=flat-square)](https://reactphp.org)
[![Tests](https://img.shields.io/badge/tests-13%20passing-success?style=flat-square)](#testing)
[![Assertions](https://img.shields.io/badge/assertions-19-blue?style=flat-square)](#testing)
[![License](https://img.shields.io/badge/license-MIT-green?style=flat-square)](LICENSE)
A tiny, protocol-agnostic ReactPHP backbone — one long-lived process, one event loop, one IPC primitive, and one graceful-shutdown story that many protocol servers attach to.
## Features
- 🧩 **One loop, many protocols** — WebSockets, WebRTC signaling, SIP and more share a single `Kernel` instead of each spinning up its own runtime
- 🔌 **Tiny `Server` contract** — implement `boot(LoopInterface)` + `shutdown()` and you're on the shared loop
- 🧵 **Socket-pair IPC** — event-driven parent↔child messaging with zero polling
- 🛎️ **Graceful shutdown** — SIGINT/SIGTERM tear every server down cleanly before the loop stops
- 🧹 **Child reaping built in** — no zombie processes from forked workers (SIGCHLD + periodic backstop)
- 🔐 **Plain or TLS listeners** — one factory, no framework coupling
- 🪶 **Dependency-light** — just `react/event-loop`, `react/socket`, `react/stream`
## Installation
```bash
composer require blax-software/reactphp-kernel
```
Requires PHP 8.1+, plus `ext-pcntl` (signals + child reaping) and `ext-sockets` (IPC) for the full feature set.
## Quick Start
Implement a `Server`, register it, `run()`:
```php
use Blax\ReactPhpKernel\Kernel;
use Blax\ReactPhpKernel\Contracts\Server;
use Blax\ReactPhpKernel\Server\SocketServerFactory;
use React\EventLoop\LoopInterface;
use React\Socket\ConnectionInterface;
final class EchoServer implements Server
{
private $socket = null;
public function name(): string
{
return 'echo';
}
public function boot(LoopInterface $loop): void
{
$this->socket = SocketServerFactory::create('0.0.0.0:9001', $loop);
$this->socket->on('connection', function (ConnectionInterface $conn) {
$conn->on('data', fn ($data) => $conn->write($data)); // echo it back
});
}
public function shutdown(): void
{
$this->socket?->close();
}
}
(new Kernel())
->reapChildren() // auto-reap forked children
->register(new EchoServer())
->onBoot(fn (Kernel $k) => fwrite(STDERR, "ready\n"))
->run(); // boots servers, installs signals, runs the loop (blocks)
```
`Ctrl-C` (SIGINT) or `SIGTERM` triggers a graceful `stop()`: every registered server's `shutdown()` runs, then the loop stops.
## What's in the box
| Class | Responsibility |
|---|---|
| `Kernel` | Owns the loop; `register()` servers; installs signals; `run()` / graceful `stop()`. |
| `Contracts\Server` | An attachable protocol server: `boot(LoopInterface)` (non-blocking) + `shutdown()`. |
| `Server\SocketServerFactory` | Plain-TCP or TLS listening socket. |
| `Ipc\SocketPairIpc` | Event-driven parent/child IPC over a Unix socket pair. |
| `Process\SignalHandler` | SIGINT/SIGTERM → graceful shutdown. |
| `Process\ChildReaper` | Reaps exited forked children (SIGCHLD + periodic backstop). |
## Why
It's the shared foundation extracted from [`blax-software/laravel-websockets`](https://github.com/blax-software/laravel-websockets) so that WebSockets and [`blax-software/laravel-webrtc`](https://github.com/blax-software/laravel-webrtc) (WebRTC signaling + a Rust/str0m media core) don't each re-implement the loop, IPC, signals and supervision. A new protocol gets the plumbing for free.
```
reactphp-kernel this package — the backbone
├─ laravel-websockets WS on the kernel
└─ laravel-webrtc WebRTC signaling on the kernel
└─ Rust/str0m core via ext-php-rs
```
## Testing
```bash
composer install
composer test
```
The suite runs against a real ReactPHP loop, with no external services.
## License
MIT. See [LICENSE](LICENSE).
## Star History
<a href="https://www.star-history.com/?repos=blax-software%2Freactphp-kernel&type=date&legend=top-left">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=blax-software/reactphp-kernel&type=date&theme=dark&legend=top-left" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=blax-software/reactphp-kernel&type=date&legend=top-left" />
<img alt="Star History Chart" src="https://api.star-history.com/chart?repos=blax-software/reactphp-kernel&type=date&legend=top-left" />
</picture>
</a>