Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled
- Remove middleware reference from Gitea Traefik labels (caused routing issues) - Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s) - Add explicit service reference in Traefik labels - Fix intermittent 504 timeouts by improving PostgreSQL connection handling Fixes Gitea unreachability via git.michaelschiemer.de
672 lines
18 KiB
Markdown
672 lines
18 KiB
Markdown
# Sockets Module Documentation
|
|
|
|
## Übersicht
|
|
|
|
Das Sockets-Modul (`src/Framework/Sockets/`) bietet eine vollständige, type-safe Abstraktion über PHP's Socket-Erweiterung. Es ermöglicht:
|
|
|
|
- **Type-safe Socket-Operationen**: Alle Socket-Operationen verwenden Value Objects statt primitiver Typen
|
|
- **TCP/UDP Server & Client**: Vollständige Server- und Client-Implementierung
|
|
- **Unix Domain Sockets**: Unterstützung für Unix Domain Sockets
|
|
- **PCNTL Integration**: Socket-Server in geforkten Worker-Prozessen
|
|
- **Async Integration**: Non-blocking Socket I/O mit Fibers
|
|
- **Connection Pooling**: Automatisches Management von Socket-Verbindungen
|
|
|
|
## Architektur
|
|
|
|
### Modulstruktur
|
|
|
|
```
|
|
src/Framework/Sockets/
|
|
├── SocketService.php # Haupt-Service (Facade)
|
|
├── SocketFactory.php # Socket-Erstellung
|
|
├── SocketServer.php # Server-Operationen
|
|
├── SocketClient.php # Client-Operationen
|
|
├── SocketConnection.php # Connection Wrapper
|
|
├── SocketConnectionPool.php # Connection Pool Management
|
|
├── SocketsInitializer.php # DI-Initializer
|
|
├── Exceptions/ # Exception-Klassen
|
|
├── ValueObjects/ # Type-safe Value Objects
|
|
└── Integration/ # PCNTL & Async Integration
|
|
```
|
|
|
|
## Value Objects
|
|
|
|
### SocketAddress
|
|
|
|
Repräsentiert eine Socket-Adresse (IPv4, IPv6 oder Unix Domain Socket).
|
|
|
|
```php
|
|
use App\Framework\Sockets\ValueObjects\SocketAddress;
|
|
|
|
// IPv4 Adresse
|
|
$address = SocketAddress::ipv4('127.0.0.1', 8080);
|
|
|
|
// IPv6 Adresse
|
|
$address = SocketAddress::ipv6('::1', 8080);
|
|
|
|
// Unix Domain Socket
|
|
$address = SocketAddress::unix('/tmp/socket.sock');
|
|
|
|
// Von String parsen
|
|
$address = SocketAddress::fromString('127.0.0.1:8080');
|
|
$address = SocketAddress::fromString('/tmp/socket.sock');
|
|
|
|
// Eigenschaften
|
|
$host = $address->getHost(); // null für Unix Sockets
|
|
$port = $address->getPort(); // null für Unix Sockets
|
|
$path = $address->getUnixPath(); // null für Network Sockets
|
|
$protocol = $address->getProtocol(); // SocketProtocol Enum
|
|
$isUnix = $address->isUnixSocket();
|
|
$isNetwork = $address->isNetworkSocket();
|
|
$string = $address->toString(); // "127.0.0.1:8080" oder "/tmp/socket.sock"
|
|
```
|
|
|
|
### SocketType
|
|
|
|
Enum für Socket-Typen.
|
|
|
|
```php
|
|
use App\Framework\Sockets\ValueObjects\SocketType;
|
|
|
|
SocketType::TCP // SOCK_STREAM
|
|
SocketType::UDP // SOCK_DGRAM
|
|
SocketType::RAW // SOCK_RAW
|
|
SocketType::RDM // SOCK_RDM
|
|
SocketType::SEQPACKET // SOCK_SEQPACKET
|
|
|
|
// Methoden
|
|
$type->getName(); // "TCP", "UDP", etc.
|
|
$type->getValue(); // SOCK_STREAM, SOCK_DGRAM, etc.
|
|
$type->isReliable(); // true für TCP, SEQPACKET
|
|
$type->isConnectionless(); // true für UDP
|
|
```
|
|
|
|
### SocketProtocol
|
|
|
|
Enum für Protokoll-Familien.
|
|
|
|
```php
|
|
use App\Framework\Sockets\ValueObjects\SocketProtocol;
|
|
|
|
SocketProtocol::IPv4 // AF_INET
|
|
SocketProtocol::IPv6 // AF_INET6
|
|
SocketProtocol::UNIX // AF_UNIX
|
|
|
|
// Methoden
|
|
$protocol->getName(); // "IPv4", "IPv6", "Unix Domain"
|
|
$protocol->getValue(); // AF_INET, AF_INET6, AF_UNIX
|
|
$protocol->isNetwork(); // true für IPv4/IPv6
|
|
$protocol->isUnix(); // true für Unix Domain
|
|
```
|
|
|
|
### SocketOption
|
|
|
|
Enum für Socket-Optionen.
|
|
|
|
```php
|
|
use App\Framework\Sockets\ValueObjects\SocketOption;
|
|
|
|
SocketOption::SO_REUSEADDR
|
|
SocketOption::SO_REUSEPORT
|
|
SocketOption::SO_KEEPALIVE
|
|
SocketOption::SO_LINGER
|
|
SocketOption::SO_RCVBUF
|
|
SocketOption::SO_SNDBUF
|
|
SocketOption::SO_RCVTIMEO
|
|
SocketOption::SO_SNDTIMEO
|
|
SocketOption::TCP_NODELAY
|
|
SocketOption::TCP_KEEPIDLE
|
|
SocketOption::TCP_KEEPINTVL
|
|
SocketOption::TCP_KEEPCNT
|
|
|
|
// Methoden
|
|
$option->getName(); // "SO_REUSEADDR", etc.
|
|
$option->getLevel(); // SOL_SOCKET oder SOL_TCP
|
|
$option->getValue(); // SO_REUSEADDR, etc.
|
|
```
|
|
|
|
### SocketResource
|
|
|
|
Type-safe Wrapper für Socket-Ressourcen mit automatischem Cleanup.
|
|
|
|
```php
|
|
use App\Framework\Sockets\ValueObjects\SocketResource;
|
|
|
|
$resource = SocketResource::fromResource($socket, $type, $protocol);
|
|
|
|
// Eigenschaften
|
|
$socketResource = $resource->getResource(); // Native Socket-Resource
|
|
$type = $resource->getType(); // SocketType
|
|
$protocol = $resource->getProtocol(); // SocketProtocol
|
|
$isClosed = $resource->isClosed();
|
|
|
|
// Manuelles Schließen (automatisch im Destructor)
|
|
$resource->close();
|
|
```
|
|
|
|
## Core Services
|
|
|
|
### SocketFactory
|
|
|
|
Factory für Socket-Erstellung mit automatischem Option-Setup.
|
|
|
|
```php
|
|
use App\Framework\Sockets\SocketFactory;
|
|
use App\Framework\Sockets\ValueObjects\SocketAddress;
|
|
use App\Framework\Sockets\ValueObjects\SocketType;
|
|
use App\Framework\Sockets\ValueObjects\SocketProtocol;
|
|
|
|
$factory = new SocketFactory();
|
|
|
|
// TCP Socket erstellen
|
|
$address = SocketAddress::ipv4('127.0.0.1', 8080);
|
|
$socket = $factory->createTcp($address);
|
|
|
|
// UDP Socket erstellen
|
|
$socket = $factory->createUdp($address);
|
|
|
|
// Unix Domain Socket erstellen
|
|
$unixAddress = SocketAddress::unix('/tmp/socket.sock');
|
|
$socket = $factory->createUnix($unixAddress);
|
|
|
|
// Generische Erstellung
|
|
$socket = $factory->createServer(SocketType::TCP, SocketProtocol::IPv4);
|
|
$socket = $factory->createClient(SocketType::TCP, SocketProtocol::IPv4);
|
|
```
|
|
|
|
### SocketServer
|
|
|
|
Server-Operationen für Socket-Verwaltung.
|
|
|
|
```php
|
|
use App\Framework\Sockets\SocketServer;
|
|
use App\Framework\Sockets\ValueObjects\SocketAddress;
|
|
use App\Framework\Sockets\ValueObjects\SocketResource;
|
|
|
|
$server = new SocketServer();
|
|
$address = SocketAddress::ipv4('0.0.0.0', 8080);
|
|
|
|
// Socket binden
|
|
$server->bind($socket, $address);
|
|
|
|
// Auf Verbindungen lauschen
|
|
$server->listen($socket, 10); // backlog = 10
|
|
|
|
// Verbindung akzeptieren (non-blocking)
|
|
$connection = $server->accept($socket);
|
|
if ($connection !== null) {
|
|
// Verbindung verarbeiten
|
|
$clientSocket = $connection->getSocket();
|
|
$clientAddress = $connection->getAddress();
|
|
}
|
|
|
|
// Socket-Auswahl (select)
|
|
$read = [$socket];
|
|
$write = [];
|
|
$except = [];
|
|
$numReady = $server->select($read, $write, $except, 1); // 1 Sekunde Timeout
|
|
|
|
// Non-blocking/Blocking Mode
|
|
$server->setNonBlocking($socket);
|
|
$server->setBlocking($socket);
|
|
```
|
|
|
|
### SocketClient
|
|
|
|
Client-Operationen für Socket-Verbindungen.
|
|
|
|
```php
|
|
use App\Framework\Sockets\SocketClient;
|
|
use App\Framework\Sockets\ValueObjects\SocketAddress;
|
|
use App\Framework\Sockets\ValueObjects\SocketResource;
|
|
|
|
$client = new SocketClient();
|
|
$address = SocketAddress::ipv4('127.0.0.1', 8080);
|
|
|
|
// Verbindung herstellen
|
|
$client->connect($socket, $address);
|
|
|
|
// Daten lesen
|
|
$data = $client->read($socket, 1024); // null wenn keine Daten (non-blocking)
|
|
|
|
// Daten schreiben
|
|
$bytesWritten = $client->write($socket, "Hello, World!");
|
|
|
|
// Daten senden (mit Flags)
|
|
$bytesSent = $client->send($socket, $data, MSG_DONTWAIT);
|
|
|
|
// Daten empfangen
|
|
$data = $client->receive($socket, 1024, MSG_DONTWAIT);
|
|
|
|
// Verbindung schließen
|
|
$client->close($socket);
|
|
```
|
|
|
|
### SocketConnection
|
|
|
|
Wrapper für Socket-Verbindungen mit Metadaten.
|
|
|
|
```php
|
|
use App\Framework\Sockets\SocketConnection;
|
|
|
|
$connection = SocketConnection::create($socketResource, $address);
|
|
|
|
// Eigenschaften
|
|
$socket = $connection->getSocket();
|
|
$address = $connection->getAddress();
|
|
$connectionId = $connection->getConnectionId();
|
|
$isClosed = $connection->isClosed();
|
|
|
|
// Verbindung schließen
|
|
$connection->close();
|
|
```
|
|
|
|
### SocketConnectionPool
|
|
|
|
Verwaltung mehrerer Socket-Verbindungen.
|
|
|
|
```php
|
|
use App\Framework\Sockets\SocketConnectionPool;
|
|
|
|
$pool = new SocketConnectionPool(
|
|
maxConnectionsPerAddress: 5,
|
|
connectionTimeoutSeconds: 300
|
|
);
|
|
|
|
// Verbindung hinzufügen
|
|
$pool->add($connection);
|
|
|
|
// Verbindung entfernen
|
|
$pool->remove($connection);
|
|
|
|
// Verbindung abrufen
|
|
$connection = $pool->get($connectionId);
|
|
$connections = $pool->getConnectionsByAddress($address);
|
|
$connection = $pool->getConnectionForAddress($address);
|
|
|
|
// Dead Connections bereinigen
|
|
$removed = $pool->cleanupDeadConnections();
|
|
|
|
// Statistiken
|
|
$count = $pool->getConnectionCount();
|
|
$allConnections = $pool->getAllConnections();
|
|
```
|
|
|
|
### SocketService
|
|
|
|
Haupt-Facade für alle Socket-Operationen.
|
|
|
|
```php
|
|
use App\Framework\Sockets\SocketService;
|
|
|
|
$socketService = $container->get(SocketService::class);
|
|
|
|
// Socket-Erstellung
|
|
$socket = $socketService->createTcp($address);
|
|
$socket = $socketService->createUdp($address);
|
|
$socket = $socketService->createUnix($address);
|
|
|
|
// Server-Operationen
|
|
$socketService->bind($socket, $address);
|
|
$socketService->listen($socket, 10);
|
|
$connection = $socketService->accept($socket);
|
|
$socketService->setNonBlocking($socket);
|
|
|
|
// Client-Operationen
|
|
$socketService->connect($socket, $address);
|
|
$data = $socketService->read($socket, 1024);
|
|
$bytes = $socketService->write($socket, $data);
|
|
|
|
// Connection Pool
|
|
$socketService->addConnection($connection);
|
|
$socketService->removeConnection($connection);
|
|
$connection = $socketService->getConnection($connectionId);
|
|
$removed = $socketService->cleanupDeadConnections();
|
|
```
|
|
|
|
## Integration
|
|
|
|
### PCNTL Integration
|
|
|
|
Socket-Server in geforkten Worker-Prozessen für Load Balancing.
|
|
|
|
```php
|
|
use App\Framework\Sockets\Integration\PcntlSocketServer;
|
|
use App\Framework\Sockets\SocketService;
|
|
use App\Framework\Pcntl\PcntlService;
|
|
use App\Framework\Sockets\ValueObjects\SocketAddress;
|
|
use App\Framework\Sockets\ValueObjects\SocketResource;
|
|
|
|
$socketService = $container->get(SocketService::class);
|
|
$pcntlService = $container->get(PcntlService::class);
|
|
|
|
$pcntlServer = new PcntlSocketServer(
|
|
socketService: $socketService,
|
|
pcntlService: $pcntlService,
|
|
maxWorkers: 4
|
|
);
|
|
|
|
// Connection Handler setzen
|
|
$pcntlServer->setConnectionHandler(function (SocketConnection $connection) {
|
|
// Verbindung verarbeiten
|
|
$socket = $connection->getSocket();
|
|
$data = $socketService->read($socket->getResource(), 1024);
|
|
// ...
|
|
});
|
|
|
|
// Server starten
|
|
$address = SocketAddress::ipv4('0.0.0.0', 8080);
|
|
$socket = $socketService->createTcp($address);
|
|
$pcntlServer->start($socket, $address, workerCount: 4);
|
|
|
|
// Server stoppen (graceful shutdown)
|
|
$pcntlServer->stop();
|
|
```
|
|
|
|
### Async Integration
|
|
|
|
Non-blocking Socket-Server mit Fibers für parallele Connection-Verarbeitung.
|
|
|
|
```php
|
|
use App\Framework\Sockets\Integration\AsyncSocketServer;
|
|
use App\Framework\Sockets\SocketService;
|
|
use App\Framework\Async\FiberManager;
|
|
use App\Framework\Sockets\ValueObjects\SocketAddress;
|
|
|
|
$socketService = $container->get(SocketService::class);
|
|
$fiberManager = $container->get(FiberManager::class);
|
|
|
|
$asyncServer = new AsyncSocketServer(
|
|
socketService: $socketService,
|
|
fiberManager: $fiberManager
|
|
);
|
|
|
|
// Server starten (gibt Fiber zurück)
|
|
$address = SocketAddress::ipv4('0.0.0.0', 8080);
|
|
$socket = $socketService->createTcp($address);
|
|
|
|
$serverFiber = $asyncServer->startAsync(
|
|
socket: $socket,
|
|
address: $address,
|
|
connectionHandler: function (SocketConnection $connection) {
|
|
// Connection in separatem Fiber verarbeiten
|
|
$socket = $connection->getSocket();
|
|
|
|
// Non-blocking lesen
|
|
$readFiber = $asyncServer->readAsync($connection, 1024);
|
|
$data = $readFiber->start();
|
|
|
|
// Non-blocking schreiben
|
|
$writeFiber = $asyncServer->writeAsync($connection, "Response");
|
|
$bytes = $writeFiber->start();
|
|
}
|
|
);
|
|
|
|
// Server-Fiber starten
|
|
$serverFiber->start();
|
|
```
|
|
|
|
## Beispiele
|
|
|
|
### Einfacher TCP Server
|
|
|
|
```php
|
|
use App\Framework\Sockets\SocketService;
|
|
use App\Framework\Sockets\ValueObjects\SocketAddress;
|
|
|
|
$socketService = $container->get(SocketService::class);
|
|
$address = SocketAddress::ipv4('0.0.0.0', 8080);
|
|
|
|
// Socket erstellen
|
|
$socket = $socketService->createTcp($address);
|
|
|
|
// Binden und lauschen
|
|
$socketService->bind($socket, $address);
|
|
$socketService->listen($socket, 10);
|
|
$socketService->setNonBlocking($socket);
|
|
|
|
// Hauptschleife
|
|
while (true) {
|
|
// Verbindung akzeptieren
|
|
$connection = $socketService->accept($socket);
|
|
|
|
if ($connection !== null) {
|
|
$clientSocket = $connection->getSocket();
|
|
|
|
// Daten lesen
|
|
$data = $socketService->read($clientSocket, 1024);
|
|
|
|
if ($data !== null) {
|
|
// Antwort senden
|
|
$socketService->write($clientSocket, "Echo: " . $data);
|
|
}
|
|
|
|
// Verbindung schließen
|
|
$connection->close();
|
|
}
|
|
|
|
usleep(10000); // 10ms
|
|
}
|
|
```
|
|
|
|
### TCP Client
|
|
|
|
```php
|
|
use App\Framework\Sockets\SocketService;
|
|
use App\Framework\Sockets\ValueObjects\SocketAddress;
|
|
|
|
$socketService = $container->get(SocketService::class);
|
|
$address = SocketAddress::ipv4('127.0.0.1', 8080);
|
|
|
|
// Client-Socket erstellen
|
|
$socket = $socketService->createClient(
|
|
SocketType::TCP,
|
|
SocketProtocol::IPv4
|
|
);
|
|
|
|
// Verbinden
|
|
$socketService->connect($socket, $address);
|
|
|
|
// Daten senden
|
|
$socketService->write($socket, "Hello, Server!");
|
|
|
|
// Antwort lesen
|
|
$response = $socketService->read($socket, 1024);
|
|
|
|
// Verbindung schließen
|
|
$socketService->close($socket);
|
|
```
|
|
|
|
### Unix Domain Socket Server
|
|
|
|
```php
|
|
use App\Framework\Sockets\SocketService;
|
|
use App\Framework\Sockets\ValueObjects\SocketAddress;
|
|
|
|
$socketService = $container->get(SocketService::class);
|
|
$address = SocketAddress::unix('/tmp/mysocket.sock');
|
|
|
|
// Socket erstellen
|
|
$socket = $socketService->createUnix($address);
|
|
|
|
// Binden und lauschen
|
|
$socketService->bind($socket, $address);
|
|
$socketService->listen($socket, 10);
|
|
|
|
// Verbindungen akzeptieren
|
|
while (true) {
|
|
$connection = $socketService->accept($socket);
|
|
|
|
if ($connection !== null) {
|
|
// Verarbeitung
|
|
$socket = $connection->getSocket();
|
|
$data = $socketService->read($socket, 1024);
|
|
// ...
|
|
}
|
|
}
|
|
```
|
|
|
|
## Migration von bestehendem Code
|
|
|
|
### Von `socket_create()` zu `SocketFactory`
|
|
|
|
**Vorher:**
|
|
```php
|
|
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
|
```
|
|
|
|
**Nachher:**
|
|
```php
|
|
$address = SocketAddress::ipv4('127.0.0.1', 8080);
|
|
$socket = $socketService->createTcp($address);
|
|
```
|
|
|
|
### Von `socket_bind()`/`socket_listen()` zu `SocketServer`
|
|
|
|
**Vorher:**
|
|
```php
|
|
socket_bind($socket, '127.0.0.1', 8080);
|
|
socket_listen($socket, 10);
|
|
```
|
|
|
|
**Nachher:**
|
|
```php
|
|
$address = SocketAddress::ipv4('127.0.0.1', 8080);
|
|
$socketService->bind($socket, $address);
|
|
$socketService->listen($socket, 10);
|
|
```
|
|
|
|
### Von `socket_accept()` zu `SocketServer::accept()`
|
|
|
|
**Vorher:**
|
|
```php
|
|
$clientSocket = socket_accept($socket);
|
|
```
|
|
|
|
**Nachher:**
|
|
```php
|
|
$connection = $socketService->accept($socket);
|
|
if ($connection !== null) {
|
|
$clientSocket = $connection->getSocket();
|
|
}
|
|
```
|
|
|
|
### Von `socket_select()` zu `SocketServer::select()`
|
|
|
|
**Vorher:**
|
|
```php
|
|
socket_select($read, $write, $except, 1);
|
|
```
|
|
|
|
**Nachher:**
|
|
```php
|
|
$numReady = $socketService->select($read, $write, $except, 1);
|
|
```
|
|
|
|
### Von `socket_read()`/`socket_write()` zu `SocketClient`
|
|
|
|
**Vorher:**
|
|
```php
|
|
$data = socket_read($socket, 1024);
|
|
socket_write($socket, $data, strlen($data));
|
|
```
|
|
|
|
**Nachher:**
|
|
```php
|
|
$data = $socketService->read($socket, 1024);
|
|
$bytes = $socketService->write($socket, $data);
|
|
```
|
|
|
|
### Von `socket_close()` zu `SocketResource` Destructor
|
|
|
|
**Vorher:**
|
|
```php
|
|
socket_close($socket);
|
|
```
|
|
|
|
**Nachher:**
|
|
```php
|
|
// Automatisch im Destructor, oder manuell:
|
|
$socket->close();
|
|
```
|
|
|
|
## Fehlerbehandlung
|
|
|
|
Das Sockets-Modul verwendet spezifische Exceptions für verschiedene Fehlertypen:
|
|
|
|
```php
|
|
use App\Framework\Sockets\Exceptions\SocketException;
|
|
use App\Framework\Sockets\Exceptions\SocketBindException;
|
|
use App\Framework\Sockets\Exceptions\SocketConnectException;
|
|
use App\Framework\Sockets\Exceptions\SocketReadException;
|
|
|
|
try {
|
|
$socketService->bind($socket, $address);
|
|
} catch (SocketBindException $e) {
|
|
// Bind-Fehler behandeln
|
|
error_log("Failed to bind: " . $e->getMessage());
|
|
}
|
|
|
|
try {
|
|
$socketService->connect($socket, $address);
|
|
} catch (SocketConnectException $e) {
|
|
// Connect-Fehler behandeln
|
|
error_log("Failed to connect: " . $e->getMessage());
|
|
}
|
|
|
|
try {
|
|
$data = $socketService->read($socket, 1024);
|
|
} catch (SocketReadException $e) {
|
|
// Read-Fehler behandeln
|
|
if ($e->getMessage() === 'Socket connection closed') {
|
|
// Verbindung geschlossen
|
|
}
|
|
}
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
1. **SocketService verwenden**: Nutze immer `SocketService` als Haupt-API statt direkter Aufrufe der einzelnen Services
|
|
2. **Value Objects**: Verwende immer Value Objects (`SocketAddress`, `SocketType`, etc.) statt primitiver Typen
|
|
3. **Resource Management**: `SocketResource` kümmert sich automatisch um Cleanup, aber manuelles Schließen ist für explizite Kontrolle möglich
|
|
4. **Non-blocking I/O**: Verwende `setNonBlocking()` für Server-Sockets, um mehrere Verbindungen parallel zu handhaben
|
|
5. **Connection Pooling**: Nutze `SocketConnectionPool` für Client-Verbindungen, die wiederverwendet werden sollen
|
|
6. **Error Handling**: Fange spezifische Exceptions (`SocketBindException`, `SocketConnectException`, etc.) für präzise Fehlerbehandlung
|
|
7. **PCNTL für Load Balancing**: Verwende `PcntlSocketServer` für Socket-Server, die mehrere Worker-Prozesse benötigen
|
|
8. **Async für Parallelität**: Verwende `AsyncSocketServer` für non-blocking I/O mit Fibers
|
|
|
|
## Dependency Injection
|
|
|
|
Alle Services werden automatisch über `SocketsInitializer` im DI-Container registriert:
|
|
|
|
```php
|
|
use App\Framework\Sockets\SocketService;
|
|
use App\Framework\Sockets\SocketFactory;
|
|
use App\Framework\Sockets\SocketServer;
|
|
use App\Framework\Sockets\SocketClient;
|
|
|
|
// Services sind im Container verfügbar
|
|
$socketService = $container->get(SocketService::class);
|
|
$factory = $container->get(SocketFactory::class);
|
|
$server = $container->get(SocketServer::class);
|
|
$client = $container->get(SocketClient::class);
|
|
```
|
|
|
|
## Framework-Kompatibilität
|
|
|
|
Das Sockets-Modul folgt allen Framework-Prinzipien:
|
|
|
|
- ✅ **Final readonly classes** wo möglich
|
|
- ✅ **Value Objects** statt Primitiven
|
|
- ✅ **Dependency Injection** überall
|
|
- ✅ **Composition** statt Inheritance
|
|
- ✅ **Strict Types** (`declare(strict_types=1)`)
|
|
- ✅ **PSR-12** Code Style
|
|
|
|
## Siehe auch
|
|
|
|
- [PCNTL Module Documentation](./pcntl-module.md) - Für PCNTL-Integration
|
|
- [Async Module Documentation](./async-module.md) - Für Async-Integration
|
|
- [Framework Guidelines](./guidelines.md) - Allgemeine Framework-Prinzipien
|
|
|