<?php
declare(strict_types=1);
namespace Worker\Socket;
use Exception;
use Socket;
class SocketUnix
{
public static function create(string $socketFile, array|null $options = []): Socket
{
if (file_exists($socketFile)) {
throw new Exception('Unable to create Unix socket, probably process is occupied');
}
$socket = socket_create(AF_UNIX, SOCK_STREAM, 0);
if (!$socket) {
throw new Exception('Unable to create Unix socket, probably process is occupied');
}
socket_set_option($socket, SOL_SOCKET, SO_KEEPALIVE, 1);
socket_set_nonblock($socket);
foreach ($options as $option => $value) {
socket_set_option($socket, SOL_SOCKET, $option, $value);
}
if (!socket_bind($socket, $socketFile)) {
throw new Exception('Unable to bind socket, please check directory permissions ' . $socketFile);
}
socket_listen($socket);
return $socket;
}
public static function createStream(string $socketFile, array|null $options = [])
{
$stream = stream_socket_server("unix://{$socketFile}", $errno, $errorMessages, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN);
if (!$stream) {
throw new Exception('Unable to create Unix socket, probably process is occupied');
}
$socket = socket_import_stream($stream);
socket_set_nonblock($socket);
socket_set_option($socket, SOL_SOCKET, SO_KEEPALIVE, 1);
foreach ($options as $option => $value) {
socket_set_option($socket, SOL_SOCKET, $option, $value);
}
return $stream;
}
public static function connect(string $socketFile, int|null $bufferSize = 1024 * 1024, array|null $options = []): Socket|false
{
$socket = socket_create(AF_UNIX, SOCK_STREAM, 0);
socket_set_option($socket, SOL_SOCKET, SO_SNDBUF, $bufferSize);
socket_set_option($socket, SOL_SOCKET, SO_RCVBUF, $bufferSize);
foreach ($options as $option => $value) {
if ($option === 'nonblock') {
socket_set_nonblock($socket);
} else {
socket_set_option($socket, SOL_SOCKET, $option, $value);
}
}
$_ = socket_connect($socket, $socketFile);
if ($_) {
return $socket;
} else {
throw new Exception("Unable to connect Unix socket, {$socketFile}");
}
}
public static function connectStream(string $socketFile, array|null $options = [])
{
$stream = stream_socket_client("unix://{$socketFile}", $errno, $errorMessages, 0);
if (!$stream) {
throw new Exception('Unable to create Unix socket, probably process is occupied');
}
$socket = socket_import_stream($stream);
socket_set_nonblock($socket);
socket_set_option($socket, SOL_SOCKET, SO_KEEPALIVE, 1);
foreach ($options as $option => $value) {
socket_set_option($socket, SOL_SOCKET, $option, $value);
}
return $stream;
}
}