1. Go to this page and download the library: Download hiblaphp/socket library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
hiblaphp / socket example snippets
use Hibla\Socket\SocketServer;
$server = new SocketServer('tcp://127.0.0.1:8080');
$server->on('connection', function ($connection) {
$connection->on('data', function (string $data) use ($connection) {
$connection->write($data);
});
$connection->on('error', function (\Throwable $e) {
echo "Connection error: " . $e->getMessage() . "\n";
});
});
$server->on('error', function (\Throwable $e) {
echo "Server error: " . $e->getMessage() . "\n";
});
echo "Listening on " . $server->getAddress() . "\n";
use Hibla\Socket\Connector;
use function Hibla\await;
$connector = new Connector();
$connection = await($connector->connect('tcp://example.com:80'));
$connection->write("GET / HTTP/1.0\r\nHost: example.com\r\n\r\n");
$connection->on('data', function (string $data) {
echo $data;
});
$connection->on('error', function (\Throwable $e) {
echo "Error: " . $e->getMessage() . "\n";
});
use Hibla\Socket\Connector;
use Hibla\Socket\Exceptions\ConnectionFailedException;
$connector = new Connector();
$connector->connect('tcp://example.com:80')
->then(function ($connection) {
$connection->on('data', function (string $data) use ($connection) {
echo $data;
$connection->close();
});
$connection->on('error', function (\Throwable $e) {
echo "Connection error: " . $e->getMessage() . "\n";
});
$connection->write("GET / HTTP/1.0\r\nHost: example.com\r\n\r\n");
})
->catch(function (ConnectionFailedException $e) {
echo "Could not connect: " . $e->getMessage() . "\n";
});
use Hibla\Socket\Connector;
use Hibla\Socket\Exceptions\ConnectionFailedException;
use function Hibla\{async, await};
await(async(function () {
$connector = new Connector();
try {
$connection = await($connector->connect('tcp://example.com:80'));
} catch (ConnectionFailedException $e) {
echo "Could not connect: " . $e->getMessage() . "\n";
return;
}
$connection->write("GET / HTTP/1.0\r\nHost: example.com\r\n\r\n");
$connection->on('data', function (string $data) use ($connection) {
echo $data;
$connection->close();
});
$connection->on('error', function (\Throwable $e) {
echo "Connection error: " . $e->getMessage() . "\n";
});
}));
use Hibla\Socket\TcpServer;
$server = new TcpServer('127.0.0.1:8080');
// or bind to all interfaces
$server = new TcpServer('0.0.0.0:8080');
// or a random available port
$server = new TcpServer('127.0.0.1:0');
echo $server->getAddress(); // tcp://127.0.0.1:43210
use Hibla\Socket\UnixServer;
$server = new UnixServer('/var/run/app.sock');
// or with scheme prefix
$server = new UnixServer('unix:///var/run/app.sock');
use Hibla\Socket\FdServer;
// From a file descriptor number
$server = new FdServer(3);
// From a php://fd URI
$server = new FdServer('php://fd/3');
use Hibla\Socket\TcpServer;
use Hibla\Socket\LimitingServer;
$tcp = new TcpServer('0.0.0.0:8080');
$server = new LimitingServer($tcp, connectionLimit: 100);
$server->on('connection', function ($connection) {
// At most 100 connections active simultaneously
});
// Mode 1: Reject (default) — accept and immediately close excess connections
$server = new LimitingServer($tcp, connectionLimit: 100, pauseOnLimit: false);
// Mode 2: Pause — stop accepting at the OS level until a slot opens
$server = new LimitingServer($tcp, connectionLimit: 100, pauseOnLimit: true);
use Hibla\Socket\Connector;
use function Hibla\await;
$connector = new Connector();
// TCP (with automatic DNS resolution)
$conn = await($connector->connect('tcp://example.com:80'));
// TLS
$conn = await($connector->connect('tls://example.com:443'));
// Unix domain socket
$conn = await($connector->connect('unix:///var/run/app.sock'));
$connector = new Connector([
// Connection timeout in seconds (default: default_socket_timeout ini)
'timeout' => 5.0,
// TCP context options (passed to stream_socket_client)
'tcp' => [
'bindto' => '192.168.1.100:0',
],
// TLS context options (see https://www.php.net/manual/en/context.ssl.php)
'tls' => [
'verify_peer' => true,
'verify_peer_name' => true,
'cafile' => '/etc/ssl/certs/ca-certificates.crt',
],
// DNS: true (system resolver), false (skip, IP only), array of nameservers,
// or a ResolverInterface instance
'dns' => ['1.1.1.1', '8.8.8.8'],
// Happy Eyeballs RFC 8305 (true by default)
'happy_eyeballs' => true,
// Pre-check if IPv6 is actually routable before attempting AAAA queries
'ipv6_precheck' => false,
// Disable any transport entirely
'unix' => false,
'tls' => false,
]);
use Hibla\Socket\TcpConnector;
use function Hibla\await;
$connector = new TcpConnector();
$conn = await($connector->connect('tcp://93.184.216.34:80'));
use Hibla\Socket\TcpConnector;
use Hibla\Socket\SecureConnector;
use function Hibla\await;
$connector = new SecureConnector(new TcpConnector(), [
'verify_peer' => true,
'verify_peer_name' => true,
'cafile' => '/etc/ssl/certs/ca-certificates.crt',
]);
$conn = await($connector->connect('tls://example.com:443'));
use Hibla\Socket\UnixConnector;
use function Hibla\await;
$connector = new UnixConnector();
$conn = await($connector->connect('unix:///var/run/app.sock'));
use Hibla\Socket\TcpConnector;
use Hibla\Socket\FixedUriConnector;
use function Hibla\await;
$connector = new FixedUriConnector(
'tcp://proxy.internal:1080',
new TcpConnector()
);
// All connect() calls go to the proxy regardless of the target URI
$conn = await($connector->connect('tcp://example.com:80'));
use Hibla\Dns\Dns;
use Hibla\Socket\Connector;
$resolver = Dns::builder()
->withNameservers(['1.1.1.1', '8.8.8.8'])
->withCache()
->build();
$connector = new Connector(['dns' => $resolver]);
$connector = new Connector(['dns' => false]);
// Disable if your environment is IPv4-only and you want to skip the delay
$connector = new Connector(['happy_eyeballs' => false]);
// Enable IPv6 pre-check to skip AAAA entirely when IPv6 isn't routable
$connector = new Connector(['ipv6_precheck' => true]);
// Write data — returns false if the internal buffer exceeds the soft limit
$connection->write("Hello, world!\n");
// Listen for incoming data
$connection->on('data', function (string $chunk) {
echo "Received: " . $chunk;
});
// Half-close — flush remaining writes then close the write side
$connection->end();
// Full close — immediately closes both sides, discarding any buffered data
$connection->close();
$connector->connect('tcp://example.com:9000')
->then(function ($connection) use ($source) {
$source->on('data', function (string $chunk) use ($connection, $source) {
if ($connection->write($chunk) === false) {
$source->pause();
}
});
$connection->on('drain', function () use ($source) {
$source->resume();
});
$connection->on('close', function () use ($source) {
$source->close();
});
$connection->on('error', function (\Throwable $e) {
echo "Error: " . $e->getMessage() . "\n";
});
});
use function Hibla\{async, await};
await(async(function () use ($connector, $source) {
$connection = await($connector->connect('tcp://example.com:9000'));
$source->on('data', function (string $chunk) use ($connection, $source) {
if ($connection->write($chunk) === false) {
$source->pause();
}
});
$connection->on('drain', fn() => $source->resume());
$connection->on('close', fn() => $source->close());
$connection->on('error', fn(\Throwable $e) => echo "Error: " . $e->getMessage() . "\n");
}));
use Hibla\Stream\ReadableResourceStream;
$file = new ReadableResourceStream(fopen('/tmp/large.bin', 'rb'));
$file->pipe($connection);
use Hibla\Socket\Connector;
use Hibla\EventLoop\Loop;
$connector = new Connector();
$promise = $connector->connect('tcp://example.com:80');
$promise->onCancel(function () {
echo "Connection attempt was cancelled\n";
});
$promise->then(function ($connection) use (&$timerId) {
Loop::cancelTimer($timerId);
$connection->write("GET / HTTP/1.0\r\n\r\n");
$connection->on('data', fn(string $data) => echo $data);
$connection->on('error', fn(\Throwable $e) => echo "Error: " . $e->getMessage() . "\n");
});
// Cancel after 2 seconds if not yet connected.
// onCancel() fires; then() and catch() do not.
$timerId = Loop::addTimer(2.0, fn() => $promise->cancel());
use Hibla\Cancellation\CancellationTokenSource;
use Hibla\Promise\Exceptions\CancelledException;
use Hibla\Socket\Connector;
use function Hibla\{async, await};
$cts = new CancellationTokenSource();
$connector = new Connector();
await(async(function () use ($cts, $connector) {
try {
$connection = await($connector->connect('tcp://example.com:80'), $cts->token);
$connection->write("GET / HTTP/1.0\r\n\r\n");
$connection->on('data', fn(string $data) => echo $data);
$connection->on('error', fn(\Throwable $e) => echo "Error: " . $e->getMessage() . "\n");
} catch (CancelledException $e) {
echo "Connection cancelled\n";
}
}));
// Cancel from anywhere — the connect promise is cancelled synchronously
$cts->cancel();
use Hibla\Cancellation\CancellationTokenSource;
use Hibla\Socket\Connector;
$cts = new CancellationTokenSource();
$connector = new Connector();
$promise = $connector->connect('tcp://example.com:80');
// Manually track — token will cancel this promise when $cts->cancel() is called
$cts->token->track($promise);
$promise->onCancel(function () {
echo "Connection cancelled\n";
});
$promise->then(function ($connection) {
$connection->write("GET / HTTP/1.0\r\n\r\n");
$connection->on('data', fn(string $data) => echo $data);
$connection->on('error', fn(\Throwable $e) => echo "Error: " . $e->getMessage() . "\n");
});
// then() and catch() do not fire — only onCancel() does
$cts->cancel();
use Hibla\Cancellation\CancellationTokenSource;
use Hibla\Promise\Exceptions\CancelledException;
use Hibla\Promise\Promise;
use Hibla\Socket\Connector;
use function Hibla\{async, await};
$cts = new CancellationTokenSource();
$connector = new Connector();
$hosts = [
'tcp://server-a.internal:9000',
'tcp://server-b.internal:9000',
'tcp://server-c.internal:9000',
];
await(async(function () use ($cts, $connector, $hosts) {
try {
$connections = await(Promise::all(array_map(
fn(string $uri) => $connector->connect($uri)
->then(function ($connection) use ($uri) {
$connection->write("PING\n");
$connection->on('error', fn(\Throwable $e) => echo "$uri error: " . $e->getMessage() . "\n");
return $connection;
}),
$hosts
)), $cts->token);
echo "All " . count($connections) . " connections established\n";
} catch (CancelledException $e) {
echo "All connections cancelled\n";
}
}));
// Cancels all three connect promises at once — synchronously
$cts->cancel();
use Hibla\Cancellation\CancellationTokenSource;
use Hibla\Promise\Exceptions\CancelledException;
use Hibla\Socket\Connector;
use function Hibla\{async, await};
$userCts = new CancellationTokenSource(); // user clicks abort
$timeoutCts = new CancellationTokenSource(10.0); // 10 second hard ceiling
// Cancels if user aborts OR 10 seconds elapse, whichever comes first
$linkedCts = CancellationTokenSource::createLinkedTokenSource(
$userCts->token,
$timeoutCts->token
);
$connector = new Connector();
await(async(function () use ($linkedCts, $connector) {
try {
$connection = await(
$connector->connect('tcp://example.com:80'),
$linkedCts->token
);
$connection->write("GET / HTTP/1.0\r\n\r\n");
$connection->on('data', fn(string $data) => echo $data);
$connection->on('error', fn(\Throwable $e) => echo "Error: " . $e->getMessage() . "\n");
} catch (CancelledException $e) {
echo "Cancelled — either user aborted or 10s timeout hit\n";
}
}));
// Wire to your UI abort button
$abortButton->onClick(fn() => $userCts->cancel());
use Hibla\Cancellation\CancellationToken;
use Hibla\Socket\Connector;
use function Hibla\{async, await};
function connectToService(
string $uri,
CancellationToken $token = null
): \Hibla\Promise\Interfaces\PromiseInterface {
$token ??= CancellationToken::none();
$connector = new Connector();
$promise = $connector->connect($uri);
$token->track($promise); // safe no-op when token is none()
return $promise;
}
// Works without a token
await(async(function () {
$conn = await(connectToService('tcp://example.com:80'));
$conn->write("PING\n");
$conn->on('error', fn(\Throwable $e) => echo "Error: " . $e->getMessage() . "\n");
}));
// Works with a token too
await(async(function () use ($cts) {
try {
$conn = await(connectToService('tcp://example.com:80', $cts->token));
$conn->write("PING\n");
$conn->on('error', fn(\Throwable $e) => echo "Error: " . $e->getMessage() . "\n");
} catch (CancelledException $e) {
echo "Cancelled\n";
}
}));