{"id":13405459,"url":"https://github.com/reactphp/socket","last_synced_at":"2025-05-14T02:05:35.467Z","repository":{"id":3249860,"uuid":"4287591","full_name":"reactphp/socket","owner":"reactphp","description":"Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP.","archived":false,"fork":false,"pushed_at":"2025-05-01T18:59:34.000Z","size":1078,"stargazers_count":1248,"open_issues_count":8,"forks_count":157,"subscribers_count":48,"default_branch":"3.x","last_synced_at":"2025-05-05T08:25:55.757Z","etag":null,"topics":["php","reactphp","server-socket","socket"],"latest_commit_sha":null,"homepage":"https://reactphp.org/socket/","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/reactphp.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["reactphp","clue","WyriHaximus"],"open_collective":"reactphp"}},"created_at":"2012-05-10T17:29:53.000Z","updated_at":"2025-05-01T19:56:30.000Z","dependencies_parsed_at":"2023-12-19T04:22:56.128Z","dependency_job_id":"9ca9fa9c-2ce3-43ba-a716-0bbff3aeebf1","html_url":"https://github.com/reactphp/socket","commit_stats":{"total_commits":511,"total_committers":32,"mean_commits":15.96875,"dds":0.5303326810176126,"last_synced_commit":"d454a1e35a482b6e3092052825227a04e56cb1cc"},"previous_names":[],"tags_count":54,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reactphp%2Fsocket","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reactphp%2Fsocket/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reactphp%2Fsocket/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reactphp%2Fsocket/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/reactphp","download_url":"https://codeload.github.com/reactphp/socket/tar.gz/refs/heads/3.x","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254052692,"owners_count":22006716,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["php","reactphp","server-socket","socket"],"created_at":"2024-07-30T19:02:02.749Z","updated_at":"2025-05-14T02:05:30.454Z","avatar_url":"https://github.com/reactphp.png","language":"PHP","readme":"# Socket\n\n[![CI status](https://github.com/reactphp/socket/workflows/CI/badge.svg)](https://github.com/reactphp/socket/actions)\n[![installs on Packagist](https://img.shields.io/packagist/dt/react/socket?color=blue\u0026label=installs%20on%20Packagist)](https://packagist.org/packages/react/socket)\n\nAsync, streaming plaintext TCP/IP and secure TLS socket server and client\nconnections for [ReactPHP](https://reactphp.org/).\n\n\u003e **Development version:** This branch contains the code for the upcoming v3\n\u003e release. For the code of the current stable v1 release, check out the\n\u003e [`1.x` branch](https://github.com/reactphp/socket/tree/1.x).\n\u003e\n\u003e The upcoming v3 release will be the way forward for this package. However,\n\u003e we will still actively support v1 for those not yet on the latest version.\n\u003e See also [installation instructions](#install) for more details.\n\nThe socket library provides re-usable interfaces for a socket-layer\nserver and client based on the [`EventLoop`](https://github.com/reactphp/event-loop)\nand [`Stream`](https://github.com/reactphp/stream) components.\nIts server component allows you to build networking servers that accept incoming\nconnections from networking clients (such as an HTTP server).\nIts client component allows you to build networking clients that establish\noutgoing connections to networking servers (such as an HTTP or database client).\nThis library provides async, streaming means for all of this, so you can\nhandle multiple concurrent connections without blocking.\n\n**Table of Contents**\n\n* [Quickstart example](#quickstart-example)\n* [Connection usage](#connection-usage)\n  * [ConnectionInterface](#connectioninterface)\n    * [getRemoteAddress()](#getremoteaddress)\n    * [getLocalAddress()](#getlocaladdress)\n* [Server usage](#server-usage)\n  * [ServerInterface](#serverinterface)\n    * [connection event](#connection-event)\n    * [error event](#error-event)\n    * [getAddress()](#getaddress)\n    * [pause()](#pause)\n    * [resume()](#resume)\n    * [close()](#close)\n  * [SocketServer](#socketserver)\n  * [Advanced server usage](#advanced-server-usage)\n    * [TcpServer](#tcpserver)\n    * [SecureServer](#secureserver)\n    * [UnixServer](#unixserver)\n    * [LimitingServer](#limitingserver)\n      * [getConnections()](#getconnections)\n* [Client usage](#client-usage)\n  * [ConnectorInterface](#connectorinterface)\n    * [connect()](#connect)\n  * [Connector](#connector)\n  * [Advanced client usage](#advanced-client-usage)\n    * [TcpConnector](#tcpconnector)\n    * [HappyEyeBallsConnector](#happyeyeballsconnector)\n    * [DnsConnector](#dnsconnector)\n    * [SecureConnector](#secureconnector)\n    * [TimeoutConnector](#timeoutconnector)\n    * [UnixConnector](#unixconnector)\n    * [FixUriConnector](#fixeduriconnector)\n* [Install](#install)\n* [Tests](#tests)\n* [License](#license)\n\n## Quickstart example\n\nHere is a server that closes the connection if you send it anything:\n\n```php\n$socket = new React\\Socket\\SocketServer('127.0.0.1:8080');\n\n$socket-\u003eon('connection', function (React\\Socket\\ConnectionInterface $connection) {\n    $connection-\u003ewrite(\"Hello \" . $connection-\u003egetRemoteAddress() . \"!\\n\");\n    $connection-\u003ewrite(\"Welcome to this amazing server!\\n\");\n    $connection-\u003ewrite(\"Here's a tip: don't say anything.\\n\");\n\n    $connection-\u003eon('data', function ($data) use ($connection) {\n        $connection-\u003eclose();\n    });\n});\n```\n\nSee also the [examples](examples).\n\nHere's a client that outputs the output of said server and then attempts to\nsend it a string:\n\n```php\n$connector = new React\\Socket\\Connector();\n\n$connector-\u003econnect('127.0.0.1:8080')-\u003ethen(function (React\\Socket\\ConnectionInterface $connection) {\n    $connection-\u003epipe(new React\\Stream\\WritableResourceStream(STDOUT));\n    $connection-\u003ewrite(\"Hello World!\\n\");\n}, function (Exception $e) {\n    echo 'Error: ' . $e-\u003egetMessage() . PHP_EOL;\n});\n```\n\n## Connection usage\n\n### ConnectionInterface\n\nThe `ConnectionInterface` is used to represent any incoming and outgoing\nconnection, such as a normal TCP/IP connection.\n\nAn incoming or outgoing connection is a duplex stream (both readable and\nwritable) that implements React's\n[`DuplexStreamInterface`](https://github.com/reactphp/stream#duplexstreaminterface).\nIt contains additional properties for the local and remote address (client IP)\nwhere this connection has been established to/from.\n\nMost commonly, instances implementing this `ConnectionInterface` are emitted\nby all classes implementing the [`ServerInterface`](#serverinterface) and\nused by all classes implementing the [`ConnectorInterface`](#connectorinterface).\n\nBecause the `ConnectionInterface` implements the underlying\n[`DuplexStreamInterface`](https://github.com/reactphp/stream#duplexstreaminterface)\nyou can use any of its events and methods as usual:\n\n```php\n$connection-\u003eon('data', function ($chunk) {\n    echo $chunk;\n});\n\n$connection-\u003eon('end', function () {\n    echo 'ended';\n});\n\n$connection-\u003eon('error', function (Exception $e) {\n    echo 'error: ' . $e-\u003egetMessage();\n});\n\n$connection-\u003eon('close', function () {\n    echo 'closed';\n});\n\n$connection-\u003ewrite($data);\n$connection-\u003eend($data = null);\n$connection-\u003eclose();\n// …\n```\n\nFor more details, see the\n[`DuplexStreamInterface`](https://github.com/reactphp/stream#duplexstreaminterface).\n\n#### getRemoteAddress()\n\nThe `getRemoteAddress(): ?string` method returns the full remote address\n(URI) where this connection has been established with.\n\n```php\n$address = $connection-\u003egetRemoteAddress();\necho 'Connection with ' . $address . PHP_EOL;\n```\n\nIf the remote address can not be determined or is unknown at this time (such as\nafter the connection has been closed), it MAY return a `NULL` value instead.\n\nOtherwise, it will return the full address (URI) as a string value, such\nas `tcp://127.0.0.1:8080`, `tcp://[::1]:80`, `tls://127.0.0.1:443`,\n`unix://example.sock` or `unix:///path/to/example.sock`.\nNote that individual URI components are application specific and depend\non the underlying transport protocol.\n\nIf this is a TCP/IP based connection and you only want the remote IP, you may\nuse something like this:\n\n```php\n$address = $connection-\u003egetRemoteAddress();\n$ip = trim(parse_url($address, PHP_URL_HOST), '[]');\necho 'Connection with ' . $ip . PHP_EOL;\n```\n\n#### getLocalAddress()\n\nThe `getLocalAddress(): ?string` method returns the full local address\n(URI) where this connection has been established with.\n\n```php\n$address = $connection-\u003egetLocalAddress();\necho 'Connection with ' . $address . PHP_EOL;\n```\n\nIf the local address can not be determined or is unknown at this time (such as\nafter the connection has been closed), it MAY return a `NULL` value instead.\n\nOtherwise, it will return the full address (URI) as a string value, such\nas `tcp://127.0.0.1:8080`, `tcp://[::1]:80`, `tls://127.0.0.1:443`,\n`unix://example.sock` or `unix:///path/to/example.sock`.\nNote that individual URI components are application specific and depend\non the underlying transport protocol.\n\nThis method complements the [`getRemoteAddress()`](#getremoteaddress) method,\nso they should not be confused.\n\nIf your `TcpServer` instance is listening on multiple interfaces (e.g. using\nthe address `0.0.0.0`), you can use this method to find out which interface\nactually accepted this connection (such as a public or local interface).\n\nIf your system has multiple interfaces (e.g. a WAN and a LAN interface),\nyou can use this method to find out which interface was actually\nused for this connection.\n\n## Server usage\n\n### ServerInterface\n\nThe `ServerInterface` is responsible for providing an interface for accepting\nincoming streaming connections, such as a normal TCP/IP connection.\n\nMost higher-level components (such as a HTTP server) accept an instance\nimplementing this interface to accept incoming streaming connections.\nThis is usually done via dependency injection, so it's fairly simple to actually\nswap this implementation against any other implementation of this interface.\nThis means that you SHOULD typehint against this interface instead of a concrete\nimplementation of this interface.\n\nBesides defining a few methods, this interface also implements the\n[`EventEmitterInterface`](https://github.com/igorw/evenement)\nwhich allows you to react to certain events.\n\n#### connection event\n\nThe `connection` event will be emitted whenever a new connection has been\nestablished, i.e. a new client connects to this server socket:\n\n```php\n$socket-\u003eon('connection', function (React\\Socket\\ConnectionInterface $connection) {\n    echo 'new connection' . PHP_EOL;\n});\n```\n\nSee also the [`ConnectionInterface`](#connectioninterface) for more details\nabout handling the incoming connection.\n\n#### error event\n\nThe `error` event will be emitted whenever there's an error accepting a new\nconnection from a client.\n\n```php\n$socket-\u003eon('error', function (Exception $e) {\n    echo 'error: ' . $e-\u003egetMessage() . PHP_EOL;\n});\n```\n\nNote that this is not a fatal error event, i.e. the server keeps listening for\nnew connections even after this event.\n\n#### getAddress()\n\nThe `getAddress(): ?string` method can be used to\nreturn the full address (URI) this server is currently listening on.\n\n```php\n$address = $socket-\u003egetAddress();\necho 'Server listening on ' . $address . PHP_EOL;\n```\n\nIf the address can not be determined or is unknown at this time (such as\nafter the socket has been closed), it MAY return a `NULL` value instead.\n\nOtherwise, it will return the full address (URI) as a string value, such\nas `tcp://127.0.0.1:8080`, `tcp://[::1]:80`, `tls://127.0.0.1:443`\n`unix://example.sock` or `unix:///path/to/example.sock`.\nNote that individual URI components are application specific and depend\non the underlying transport protocol.\n\nIf this is a TCP/IP based server and you only want the local port, you may\nuse something like this:\n\n```php\n$address = $socket-\u003egetAddress();\n$port = parse_url($address, PHP_URL_PORT);\necho 'Server listening on port ' . $port . PHP_EOL;\n```\n\n#### pause()\n\nThe `pause(): void` method can be used to\npause accepting new incoming connections.\n\nRemoves the socket resource from the EventLoop and thus stop accepting\nnew connections. Note that the listening socket stays active and is not\nclosed.\n\nThis means that new incoming connections will stay pending in the\noperating system backlog until its configurable backlog is filled.\nOnce the backlog is filled, the operating system may reject further\nincoming connections until the backlog is drained again by resuming\nto accept new connections.\n\nOnce the server is paused, no futher `connection` events SHOULD\nbe emitted.\n\n```php\n$socket-\u003epause();\n\n$socket-\u003eon('connection', assertShouldNeverCalled());\n```\n\nThis method is advisory-only, though generally not recommended, the\nserver MAY continue emitting `connection` events.\n\nUnless otherwise noted, a successfully opened server SHOULD NOT start\nin paused state.\n\nYou can continue processing events by calling `resume()` again.\n\nNote that both methods can be called any number of times, in particular\ncalling `pause()` more than once SHOULD NOT have any effect.\nSimilarly, calling this after `close()` is a NO-OP.\n\n#### resume()\n\nThe `resume(): void` method can be used to\nresume accepting new incoming connections.\n\nRe-attach the socket resource to the EventLoop after a previous `pause()`.\n\n```php\n$socket-\u003epause();\n\nLoop::addTimer(1.0, function () use ($socket) {\n    $socket-\u003eresume();\n});\n```\n\nNote that both methods can be called any number of times, in particular\ncalling `resume()` without a prior `pause()` SHOULD NOT have any effect.\nSimilarly, calling this after `close()` is a NO-OP.\n\n#### close()\n\nThe `close(): void` method can be used to\nshut down this listening socket.\n\nThis will stop listening for new incoming connections on this socket.\n\n```php\necho 'Shutting down server socket' . PHP_EOL;\n$socket-\u003eclose();\n```\n\nCalling this method more than once on the same instance is a NO-OP.\n\n### SocketServer\n\nThe `SocketServer` class is the main class in this package that implements the\n[`ServerInterface`](#serverinterface) and allows you to accept incoming\nstreaming connections, such as plaintext TCP/IP or secure TLS connection streams.\n\nIn order to accept plaintext TCP/IP connections, you can simply pass a host\nand port combination like this:\n\n```php\n$socket = new React\\Socket\\SocketServer('127.0.0.1:8080');\n```\n\nListening on the localhost address `127.0.0.1` means it will not be reachable from\noutside of this system.\nIn order to change the host the socket is listening on, you can provide an IP\naddress of an interface or use the special `0.0.0.0` address to listen on all\ninterfaces:\n\n```php\n$socket = new React\\Socket\\SocketServer('0.0.0.0:8080');\n```\n\nIf you want to listen on an IPv6 address, you MUST enclose the host in square\nbrackets:\n\n```php\n$socket = new React\\Socket\\SocketServer('[::1]:8080');\n```\n\nIn order to use a random port assignment, you can use the port `0`:\n\n```php\n$socket = new React\\Socket\\SocketServer('127.0.0.1:0');\n$address = $socket-\u003egetAddress();\n```\n\nTo listen on a Unix domain socket (UDS) path, you MUST prefix the URI with the\n`unix://` scheme:\n\n```php\n$socket = new React\\Socket\\SocketServer('unix:///tmp/server.sock');\n```\n\nIn order to listen on an existing file descriptor (FD) number, you MUST prefix\nthe URI with `php://fd/` like this:\n\n```php\n$socket = new React\\Socket\\SocketServer('php://fd/3');\n```\n\nIf the given URI is invalid, does not contain a port, any other scheme or if it\ncontains a hostname, it will throw an `InvalidArgumentException`:\n\n```php\n// throws InvalidArgumentException due to missing port\n$socket = new React\\Socket\\SocketServer('127.0.0.1');\n```\n\nIf the given URI appears to be valid, but listening on it fails (such as if port\nis already in use or port below 1024 may require root access etc.), it will\nthrow a `RuntimeException`:\n\n```php\n$first = new React\\Socket\\SocketServer('127.0.0.1:8080');\n\n// throws RuntimeException because port is already in use\n$second = new React\\Socket\\SocketServer('127.0.0.1:8080');\n```\n\n\u003e Note that these error conditions may vary depending on your system and/or\n  configuration.\n  See the exception message and code for more details about the actual error\n  condition.\n\nOptionally, you can specify [TCP socket context options](https://www.php.net/manual/en/context.socket.php)\nfor the underlying stream socket resource like this:\n\n```php\n$socket = new React\\Socket\\SocketServer('[::1]:8080', [\n    'tcp' =\u003e [\n        'backlog' =\u003e 200,\n        'so_reuseport' =\u003e true,\n        'ipv6_v6only' =\u003e true\n    ]\n]);\n```\n\n\u003e Note that available [socket context options](https://www.php.net/manual/en/context.socket.php),\n  their defaults and effects of changing these may vary depending on your system\n  and/or PHP version.\n  Passing unknown context options has no effect.\n  The `backlog` context option defaults to `511` unless given explicitly.\n\nYou can start a secure TLS (formerly known as SSL) server by simply prepending\nthe `tls://` URI scheme.\nInternally, it will wait for plaintext TCP/IP connections and then performs a\nTLS handshake for each connection.\nIt thus requires valid [TLS context options](https://www.php.net/manual/en/context.ssl.php),\nwhich in its most basic form may look something like this if you're using a\nPEM encoded certificate file:\n\n```php\n$socket = new React\\Socket\\SocketServer('tls://127.0.0.1:8080', [\n    'tls' =\u003e [\n        'local_cert' =\u003e 'server.pem'\n    ]\n]);\n```\n\n\u003e Note that the certificate file will not be loaded on instantiation but when an\n  incoming connection initializes its TLS context.\n  This implies that any invalid certificate file paths or contents will only cause\n  an `error` event at a later time.\n\nIf your private key is encrypted with a passphrase, you have to specify it\nlike this:\n\n```php\n$socket = new React\\Socket\\SocketServer('tls://127.0.0.1:8000', [\n    'tls' =\u003e [\n        'local_cert' =\u003e 'server.pem',\n        'passphrase' =\u003e 'secret'\n    ]\n]);\n```\n\nBy default, this server supports TLSv1.0+ and excludes support for legacy\nSSLv2/SSLv3. You can also explicitly choose the TLS version you\nwant to negotiate with the remote side:\n\n```php\n$socket = new React\\Socket\\SocketServer('tls://127.0.0.1:8000', [\n    'tls' =\u003e [\n        'local_cert' =\u003e 'server.pem',\n        'crypto_method' =\u003e STREAM_CRYPTO_METHOD_TLSv1_2_SERVER\n    ]\n]);\n```\n\n\u003e Note that available [TLS context options](https://www.php.net/manual/en/context.ssl.php),\n  their defaults and effects of changing these may vary depending on your system\n  and/or PHP version.\n  The outer context array allows you to also use `tcp` (and possibly more)\n  context options at the same time.\n  Passing unknown context options has no effect.\n  If you do not use the `tls://` scheme, then passing `tls` context options\n  has no effect.\n\nWhenever a client connects, it will emit a `connection` event with a connection\ninstance implementing [`ConnectionInterface`](#connectioninterface):\n\n```php\n$socket-\u003eon('connection', function (React\\Socket\\ConnectionInterface $connection) {\n    echo 'Plaintext connection from ' . $connection-\u003egetRemoteAddress() . PHP_EOL;\n    \n    $connection-\u003ewrite('hello there!' . PHP_EOL);\n    …\n});\n```\n\nSee also the [`ServerInterface`](#serverinterface) for more details.\n\nThis class takes an optional `LoopInterface|null $loop` parameter that can be used to\npass the event loop instance to use for this object. You can use a `null` value\nhere in order to use the [default loop](https://github.com/reactphp/event-loop#loop).\nThis value SHOULD NOT be given unless you're sure you want to explicitly use a\ngiven event loop instance.\n\n\u003e Note that the `SocketServer` class is a concrete implementation for TCP/IP sockets.\n  If you want to typehint in your higher-level protocol implementation, you SHOULD\n  use the generic [`ServerInterface`](#serverinterface) instead.\n\n### Advanced server usage\n\n#### TcpServer\n\nThe `TcpServer` class implements the [`ServerInterface`](#serverinterface) and\nis responsible for accepting plaintext TCP/IP connections.\n\n```php\n$server = new React\\Socket\\TcpServer(8080);\n```\n\nAs above, the `$uri` parameter can consist of only a port, in which case the\nserver will default to listening on the localhost address `127.0.0.1`,\nwhich means it will not be reachable from outside of this system.\n\nIn order to use a random port assignment, you can use the port `0`:\n\n```php\n$server = new React\\Socket\\TcpServer(0);\n$address = $server-\u003egetAddress();\n```\n\nIn order to change the host the socket is listening on, you can provide an IP\naddress through the first parameter provided to the constructor, optionally\npreceded by the `tcp://` scheme:\n\n```php\n$server = new React\\Socket\\TcpServer('192.168.0.1:8080');\n```\n\nIf you want to listen on an IPv6 address, you MUST enclose the host in square\nbrackets:\n\n```php\n$server = new React\\Socket\\TcpServer('[::1]:8080');\n```\n\nIf the given URI is invalid, does not contain a port, any other scheme or if it\ncontains a hostname, it will throw an `InvalidArgumentException`:\n\n```php\n// throws InvalidArgumentException due to missing port\n$server = new React\\Socket\\TcpServer('127.0.0.1');\n```\n\nIf the given URI appears to be valid, but listening on it fails (such as if port\nis already in use or port below 1024 may require root access etc.), it will\nthrow a `RuntimeException`:\n\n```php\n$first = new React\\Socket\\TcpServer(8080);\n\n// throws RuntimeException because port is already in use\n$second = new React\\Socket\\TcpServer(8080);\n```\n\n\u003e Note that these error conditions may vary depending on your system and/or\nconfiguration.\nSee the exception message and code for more details about the actual error\ncondition.\n\nThis class takes an optional `LoopInterface|null $loop` parameter that can be used to\npass the event loop instance to use for this object. You can use a `null` value\nhere in order to use the [default loop](https://github.com/reactphp/event-loop#loop).\nThis value SHOULD NOT be given unless you're sure you want to explicitly use a\ngiven event loop instance.\n\nOptionally, you can specify [socket context options](https://www.php.net/manual/en/context.socket.php)\nfor the underlying stream socket resource like this:\n\n```php\n$server = new React\\Socket\\TcpServer('[::1]:8080', null, [\n    'backlog' =\u003e 200,\n    'so_reuseport' =\u003e true,\n    'ipv6_v6only' =\u003e true\n]);\n```\n\n\u003e Note that available [socket context options](https://www.php.net/manual/en/context.socket.php),\ntheir defaults and effects of changing these may vary depending on your system\nand/or PHP version.\nPassing unknown context options has no effect.\nThe `backlog` context option defaults to `511` unless given explicitly.\n\nWhenever a client connects, it will emit a `connection` event with a connection\ninstance implementing [`ConnectionInterface`](#connectioninterface):\n\n```php\n$server-\u003eon('connection', function (React\\Socket\\ConnectionInterface $connection) {\n    echo 'Plaintext connection from ' . $connection-\u003egetRemoteAddress() . PHP_EOL;\n    \n    $connection-\u003ewrite('hello there!' . PHP_EOL);\n    …\n});\n```\n\nSee also the [`ServerInterface`](#serverinterface) for more details.\n\n#### SecureServer\n\nThe `SecureServer` class implements the [`ServerInterface`](#serverinterface)\nand is responsible for providing a secure TLS (formerly known as SSL) server.\n\nIt does so by wrapping a [`TcpServer`](#tcpserver) instance which waits for plaintext\nTCP/IP connections and then performs a TLS handshake for each connection.\nIt thus requires valid [TLS context options](https://www.php.net/manual/en/context.ssl.php),\nwhich in its most basic form may look something like this if you're using a\nPEM encoded certificate file:\n\n```php\n$server = new React\\Socket\\TcpServer(8000);\n$server = new React\\Socket\\SecureServer($server, null, [\n    'local_cert' =\u003e 'server.pem'\n]);\n```\n\n\u003e Note that the certificate file will not be loaded on instantiation but when an\nincoming connection initializes its TLS context.\nThis implies that any invalid certificate file paths or contents will only cause\nan `error` event at a later time.\n\nIf your private key is encrypted with a passphrase, you have to specify it\nlike this:\n\n```php\n$server = new React\\Socket\\TcpServer(8000);\n$server = new React\\Socket\\SecureServer($server, null, [\n    'local_cert' =\u003e 'server.pem',\n    'passphrase' =\u003e 'secret'\n]);\n```\n\nBy default, this server supports TLSv1.0+ and excludes support for legacy\nSSLv2/SSLv3. You can also explicitly choose the TLS version you\nwant to negotiate with the remote side:\n\n```php\n$server = new React\\Socket\\TcpServer(8000);\n$server = new React\\Socket\\SecureServer($server, null, [\n    'local_cert' =\u003e 'server.pem',\n    'crypto_method' =\u003e STREAM_CRYPTO_METHOD_TLSv1_2_SERVER\n]);\n```\n\n\u003e Note that available [TLS context options](https://www.php.net/manual/en/context.ssl.php),\ntheir defaults and effects of changing these may vary depending on your system\nand/or PHP version.\nPassing unknown context options has no effect.\n\nWhenever a client completes the TLS handshake, it will emit a `connection` event\nwith a connection instance implementing [`ConnectionInterface`](#connectioninterface):\n\n```php\n$server-\u003eon('connection', function (React\\Socket\\ConnectionInterface $connection) {\n    echo 'Secure connection from' . $connection-\u003egetRemoteAddress() . PHP_EOL;\n    \n    $connection-\u003ewrite('hello there!' . PHP_EOL);\n    …\n});\n```\n\nWhenever a client fails to perform a successful TLS handshake, it will emit an\n`error` event and then close the underlying TCP/IP connection:\n\n```php\n$server-\u003eon('error', function (Exception $e) {\n    echo 'Error' . $e-\u003egetMessage() . PHP_EOL;\n});\n```\n\nSee also the [`ServerInterface`](#serverinterface) for more details.\n\nNote that the `SecureServer` class is a concrete implementation for TLS sockets.\nIf you want to typehint in your higher-level protocol implementation, you SHOULD\nuse the generic [`ServerInterface`](#serverinterface) instead.\n\nThis class takes an optional `LoopInterface|null $loop` parameter that can be used to\npass the event loop instance to use for this object. You can use a `null` value\nhere in order to use the [default loop](https://github.com/reactphp/event-loop#loop).\nThis value SHOULD NOT be given unless you're sure you want to explicitly use a\ngiven event loop instance.\n\n\u003e Advanced usage: Despite allowing any `ServerInterface` as first parameter,\nyou SHOULD pass a `TcpServer` instance as first parameter, unless you\nknow what you're doing.\nInternally, the `SecureServer` has to set the required TLS context options on\nthe underlying stream resources.\nThese resources are not exposed through any of the interfaces defined in this\npackage, but only through the internal `Connection` class.\nThe `TcpServer` class is guaranteed to emit connections that implement\nthe `ConnectionInterface` and uses the internal `Connection` class in order to\nexpose these underlying resources.\nIf you use a custom `ServerInterface` and its `connection` event does not\nmeet this requirement, the `SecureServer` will emit an `error` event and\nthen close the underlying connection.\n\n#### UnixServer\n\nThe `UnixServer` class implements the [`ServerInterface`](#serverinterface) and\nis responsible for accepting connections on Unix domain sockets (UDS).\n\n```php\n$server = new React\\Socket\\UnixServer('/tmp/server.sock');\n```\n\nAs above, the `$uri` parameter can consist of only a socket path or socket path\nprefixed by the `unix://` scheme.\n\nIf the given URI appears to be valid, but listening on it fails (such as if the\nsocket is already in use or the file not accessible etc.), it will throw a\n`RuntimeException`:\n\n```php\n$first = new React\\Socket\\UnixServer('/tmp/same.sock');\n\n// throws RuntimeException because socket is already in use\n$second = new React\\Socket\\UnixServer('/tmp/same.sock');\n```\n\n\u003e Note that these error conditions may vary depending on your system and/or\n  configuration.\n  In particular, Zend PHP does only report \"Unknown error\" when the UDS path\n  already exists and can not be bound. You may want to check `is_file()` on the\n  given UDS path to report a more user-friendly error message in this case.\n  See the exception message and code for more details about the actual error\n  condition.\n\nThis class takes an optional `LoopInterface|null $loop` parameter that can be used to\npass the event loop instance to use for this object. You can use a `null` value\nhere in order to use the [default loop](https://github.com/reactphp/event-loop#loop).\nThis value SHOULD NOT be given unless you're sure you want to explicitly use a\ngiven event loop instance.\n\nWhenever a client connects, it will emit a `connection` event with a connection\ninstance implementing [`ConnectionInterface`](#connectioninterface):\n\n```php\n$server-\u003eon('connection', function (React\\Socket\\ConnectionInterface $connection) {\n    echo 'New connection' . PHP_EOL;\n\n    $connection-\u003ewrite('hello there!' . PHP_EOL);\n    …\n});\n```\n\nSee also the [`ServerInterface`](#serverinterface) for more details.\n\n#### LimitingServer\n\nThe `LimitingServer` decorator wraps a given `ServerInterface` and is responsible\nfor limiting and keeping track of open connections to this server instance.\n\nWhenever the underlying server emits a `connection` event, it will check its\nlimits and then either\n - keep track of this connection by adding it to the list of\n   open connections and then forward the `connection` event\n - or reject (close) the connection when its limits are exceeded and will\n   forward an `error` event instead.\n\nWhenever a connection closes, it will remove this connection from the list of\nopen connections.\n\n```php\n$server = new React\\Socket\\LimitingServer($server, 100);\n$server-\u003eon('connection', function (React\\Socket\\ConnectionInterface $connection) {\n    $connection-\u003ewrite('hello there!' . PHP_EOL);\n    …\n});\n```\n\nSee also the [second example](examples) for more details.\n\nYou have to pass a maximum number of open connections to ensure\nthe server will automatically reject (close) connections once this limit\nis exceeded. In this case, it will emit an `error` event to inform about\nthis and no `connection` event will be emitted.\n\n```php\n$server = new React\\Socket\\LimitingServer($server, 100);\n$server-\u003eon('connection', function (React\\Socket\\ConnectionInterface $connection) {\n    $connection-\u003ewrite('hello there!' . PHP_EOL);\n    …\n});\n```\n\nYou MAY pass a `null` limit in order to put no limit on the number of\nopen connections and keep accepting new connection until you run out of\noperating system resources (such as open file handles). This may be\nuseful if you do not want to take care of applying a limit but still want\nto use the `getConnections()` method.\n\nYou can optionally configure the server to pause accepting new\nconnections once the connection limit is reached. In this case, it will\npause the underlying server and no longer process any new connections at\nall, thus also no longer closing any excessive connections.\nThe underlying operating system is responsible for keeping a backlog of\npending connections until its limit is reached, at which point it will\nstart rejecting further connections.\nOnce the server is below the connection limit, it will continue consuming\nconnections from the backlog and will process any outstanding data on\neach connection.\nThis mode may be useful for some protocols that are designed to wait for\na response message (such as HTTP), but may be less useful for other\nprotocols that demand immediate responses (such as a \"welcome\" message in\nan interactive chat).\n\n```php\n$server = new React\\Socket\\LimitingServer($server, 100, true);\n$server-\u003eon('connection', function (React\\Socket\\ConnectionInterface $connection) {\n    $connection-\u003ewrite('hello there!' . PHP_EOL);\n    …\n});\n```\n\n##### getConnections()\n\nThe `getConnections(): ConnectionInterface[]` method can be used to\nreturn an array with all currently active connections.\n\n```php\nforeach ($server-\u003egetConnection() as $connection) {\n    $connection-\u003ewrite('Hi!');\n}\n```\n\n## Client usage\n\n### ConnectorInterface\n\nThe `ConnectorInterface` is responsible for providing an interface for\nestablishing streaming connections, such as a normal TCP/IP connection.\n\nThis is the main interface defined in this package and it is used throughout\nReact's vast ecosystem.\n\nMost higher-level components (such as HTTP, database or other networking\nservice clients) accept an instance implementing this interface to create their\nTCP/IP connection to the underlying networking service.\nThis is usually done via dependency injection, so it's fairly simple to actually\nswap this implementation against any other implementation of this interface.\n\nThe interface only offers a single method:\n\n#### connect()\n\nThe `connect(string $uri): PromiseInterface\u003cConnectionInterface\u003e` method can be used to\ncreate a streaming connection to the given remote address.\n\nIt returns a [Promise](https://github.com/reactphp/promise) which either\nfulfills with a stream implementing [`ConnectionInterface`](#connectioninterface)\non success or rejects with an `Exception` if the connection is not successful:\n\n```php\n$connector-\u003econnect('google.com:443')-\u003ethen(\n    function (React\\Socket\\ConnectionInterface $connection) {\n        // connection successfully established\n    },\n    function (Exception $error) {\n        // failed to connect due to $error\n    }\n);\n```\n\nSee also [`ConnectionInterface`](#connectioninterface) for more details.\n\nThe returned Promise MUST be implemented in such a way that it can be\ncancelled when it is still pending. Cancelling a pending promise MUST\nreject its value with an `Exception`. It SHOULD clean up any underlying\nresources and references as applicable:\n\n```php\n$promise = $connector-\u003econnect($uri);\n\n$promise-\u003ecancel();\n```\n\n### Connector\n\nThe `Connector` class is the main class in this package that implements the\n[`ConnectorInterface`](#connectorinterface) and allows you to create streaming connections.\n\nYou can use this connector to create any kind of streaming connections, such\nas plaintext TCP/IP, secure TLS or local Unix connection streams.\n\nIt binds to the main event loop and can be used like this:\n\n```php\n$connector = new React\\Socket\\Connector();\n\n$connector-\u003econnect($uri)-\u003ethen(function (React\\Socket\\ConnectionInterface $connection) {\n    $connection-\u003ewrite('...');\n    $connection-\u003eend();\n}, function (Exception $e) {\n    echo 'Error: ' . $e-\u003egetMessage() . PHP_EOL;\n});\n```\n\nIn order to create a plaintext TCP/IP connection, you can simply pass a host\nand port combination like this:\n\n```php\n$connector-\u003econnect('www.google.com:80')-\u003ethen(function (React\\Socket\\ConnectionInterface $connection) {\n    $connection-\u003ewrite('...');\n    $connection-\u003eend();\n});\n```\n\n\u003e If you do no specify a URI scheme in the destination URI, it will assume\n  `tcp://` as a default and establish a plaintext TCP/IP connection.\n  Note that TCP/IP connections require a host and port part in the destination\n  URI like above, all other URI components are optional.\n\nIn order to create a secure TLS connection, you can use the `tls://` URI scheme\nlike this:\n\n```php\n$connector-\u003econnect('tls://www.google.com:443')-\u003ethen(function (React\\Socket\\ConnectionInterface $connection) {\n    $connection-\u003ewrite('...');\n    $connection-\u003eend();\n});\n```\n\nIn order to create a local Unix domain socket connection, you can use the\n`unix://` URI scheme like this:\n\n```php\n$connector-\u003econnect('unix:///tmp/demo.sock')-\u003ethen(function (React\\Socket\\ConnectionInterface $connection) {\n    $connection-\u003ewrite('...');\n    $connection-\u003eend();\n});\n```\n\n\u003e The [`getRemoteAddress()`](#getremoteaddress) method will return the target\n  Unix domain socket (UDS) path as given to the `connect()` method, including\n  the `unix://` scheme, for example `unix:///tmp/demo.sock`.\n  The [`getLocalAddress()`](#getlocaladdress) method will most likely return a\n  `null` value as this value is not applicable to UDS connections here.\n\nUnder the hood, the `Connector` is implemented as a *higher-level facade*\nfor the lower-level connectors implemented in this package. This means it\nalso shares all of their features and implementation details.\nIf you want to typehint in your higher-level protocol implementation, you SHOULD\nuse the generic [`ConnectorInterface`](#connectorinterface) instead.\n\nAs of `v1.4.0`, the `Connector` class defaults to using the\n[happy eyeballs algorithm](https://en.wikipedia.org/wiki/Happy_Eyeballs) to\nautomatically connect over IPv4 or IPv6 when a hostname is given.\nThis automatically attempts to connect using both IPv4 and IPv6 at the same time\n(preferring IPv6), thus avoiding the usual problems faced by users with imperfect\nIPv6 connections or setups.\nIf you want to revert to the old behavior of only doing an IPv4 lookup and\nonly attempt a single IPv4 connection, you can set up the `Connector` like this:\n\n```php\n$connector = new React\\Socket\\Connector([\n    'happy_eyeballs' =\u003e false\n]);\n```\n\nSimilarly, you can also affect the default DNS behavior as follows.\nThe `Connector` class will try to detect your system DNS settings (and uses\nGoogle's public DNS server `8.8.8.8` as a fallback if unable to determine your\nsystem settings) to resolve all public hostnames into underlying IP addresses by\ndefault.\nIf you explicitly want to use a custom DNS server (such as a local DNS relay or\na company wide DNS server), you can set up the `Connector` like this:\n\n```php\n$connector = new React\\Socket\\Connector([\n    'dns' =\u003e '127.0.1.1'\n]);\n\n$connector-\u003econnect('localhost:80')-\u003ethen(function (React\\Socket\\ConnectionInterface $connection) {\n    $connection-\u003ewrite('...');\n    $connection-\u003eend();\n});\n```\n\nIf you do not want to use a DNS resolver at all and want to connect to IP\naddresses only, you can also set up your `Connector` like this:\n\n```php\n$connector = new React\\Socket\\Connector([\n    'dns' =\u003e false\n]);\n\n$connector-\u003econnect('127.0.0.1:80')-\u003ethen(function (React\\Socket\\ConnectionInterface $connection) {\n    $connection-\u003ewrite('...');\n    $connection-\u003eend();\n});\n```\n\nAdvanced: If you need a custom DNS `React\\Dns\\Resolver\\ResolverInterface` instance, you\ncan also set up your `Connector` like this:\n\n```php\n$dnsResolverFactory = new React\\Dns\\Resolver\\Factory();\n$resolver = $dnsResolverFactory-\u003ecreateCached('127.0.1.1');\n\n$connector = new React\\Socket\\Connector([\n    'dns' =\u003e $resolver\n]);\n\n$connector-\u003econnect('localhost:80')-\u003ethen(function (React\\Socket\\ConnectionInterface $connection) {\n    $connection-\u003ewrite('...');\n    $connection-\u003eend();\n});\n```\n\nBy default, the `tcp://` and `tls://` URI schemes will use timeout value that\nrespects your `default_socket_timeout` ini setting (which defaults to 60s).\nIf you want a custom timeout value, you can simply pass this like this:\n\n```php\n$connector = new React\\Socket\\Connector([\n    'timeout' =\u003e 10.0\n]);\n```\n\nSimilarly, if you do not want to apply a timeout at all and let the operating\nsystem handle this, you can pass a boolean flag like this:\n\n```php\n$connector = new React\\Socket\\Connector([\n    'timeout' =\u003e false\n]);\n```\n\nBy default, the `Connector` supports the `tcp://`, `tls://` and `unix://`\nURI schemes. If you want to explicitly prohibit any of these, you can simply\npass boolean flags like this:\n\n```php\n// only allow secure TLS connections\n$connector = new React\\Socket\\Connector([\n    'tcp' =\u003e false,\n    'tls' =\u003e true,\n    'unix' =\u003e false,\n));\n\n$connector-\u003econnect('tls://google.com:443')-\u003ethen(function (React\\Socket\\ConnectionInterface $connection) {\n    $connection-\u003ewrite('...');\n    $connection-\u003eend();\n});\n```\n\nThe `tcp://` and `tls://` also accept additional context options passed to\nthe underlying connectors.\nIf you want to explicitly pass additional context options, you can simply\npass arrays of context options like this:\n\n```php\n// allow insecure TLS connections\n$connector = new React\\Socket\\Connector([\n    'tcp' =\u003e [\n        'bindto' =\u003e '192.168.0.1:0'\n    ],\n    'tls' =\u003e [\n        'verify_peer' =\u003e false,\n        'verify_peer_name' =\u003e false\n    ],\n]);\n\n$connector-\u003econnect('tls://localhost:443')-\u003ethen(function (React\\Socket\\ConnectionInterface $connection) {\n    $connection-\u003ewrite('...');\n    $connection-\u003eend();\n});\n```\n\nBy default, this connector supports TLSv1.0+ and excludes support for legacy\nSSLv2/SSLv3. You can also explicitly choose the TLS version you\nwant to negotiate with the remote side:\n\n```php\n$connector = new React\\Socket\\Connector([\n    'tls' =\u003e [\n        'crypto_method' =\u003e STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT\n    ]\n]);\n```\n\n\u003e For more details about context options, please refer to the PHP documentation\n  about [socket context options](https://www.php.net/manual/en/context.socket.php)\n  and [SSL context options](https://www.php.net/manual/en/context.ssl.php).\n\nAdvanced: By default, the `Connector` supports the `tcp://`, `tls://` and\n`unix://` URI schemes.\nFor this, it sets up the required connector classes automatically.\nIf you want to explicitly pass custom connectors for any of these, you can simply\npass an instance implementing the `ConnectorInterface` like this:\n\n```php\n$dnsResolverFactory = new React\\Dns\\Resolver\\Factory();\n$resolver = $dnsResolverFactory-\u003ecreateCached('127.0.1.1');\n$tcp = new React\\Socket\\HappyEyeBallsConnector(null, new React\\Socket\\TcpConnector(), $resolver);\n\n$tls = new React\\Socket\\SecureConnector($tcp);\n\n$unix = new React\\Socket\\UnixConnector();\n\n$connector = new React\\Socket\\Connector([\n    'tcp' =\u003e $tcp,\n    'tls' =\u003e $tls,\n    'unix' =\u003e $unix,\n\n    'dns' =\u003e false,\n    'timeout' =\u003e false,\n]);\n\n$connector-\u003econnect('google.com:80')-\u003ethen(function (React\\Socket\\ConnectionInterface $connection) {\n    $connection-\u003ewrite('...');\n    $connection-\u003eend();\n});\n```\n\n\u003e Internally, the `tcp://` connector will always be wrapped by the DNS resolver,\n  unless you disable DNS like in the above example. In this case, the `tcp://`\n  connector receives the actual hostname instead of only the resolved IP address\n  and is thus responsible for performing the lookup.\n  Internally, the automatically created `tls://` connector will always wrap the\n  underlying `tcp://` connector for establishing the underlying plaintext\n  TCP/IP connection before enabling secure TLS mode. If you want to use a custom\n  underlying `tcp://` connector for secure TLS connections only, you may\n  explicitly pass a `tls://` connector like above instead.\n  Internally, the `tcp://` and `tls://` connectors will always be wrapped by\n  `TimeoutConnector`, unless you disable timeouts like in the above example.\n\nThis class takes an optional `LoopInterface|null $loop` parameter that can be used to\npass the event loop instance to use for this object. You can use a `null` value\nhere in order to use the [default loop](https://github.com/reactphp/event-loop#loop).\nThis value SHOULD NOT be given unless you're sure you want to explicitly use a\ngiven event loop instance.\n\n### Advanced client usage\n\n#### TcpConnector\n\nThe `TcpConnector` class implements the\n[`ConnectorInterface`](#connectorinterface) and allows you to create plaintext\nTCP/IP connections to any IP-port-combination:\n\n```php\n$tcpConnector = new React\\Socket\\TcpConnector();\n\n$tcpConnector-\u003econnect('127.0.0.1:80')-\u003ethen(function (React\\Socket\\ConnectionInterface $connection) {\n    $connection-\u003ewrite('...');\n    $connection-\u003eend();\n});\n```\n\nSee also the [examples](examples).\n\nPending connection attempts can be cancelled by cancelling its pending promise like so:\n\n```php\n$promise = $tcpConnector-\u003econnect('127.0.0.1:80');\n\n$promise-\u003ecancel();\n```\n\nCalling `cancel()` on a pending promise will close the underlying socket\nresource, thus cancelling the pending TCP/IP connection, and reject the\nresulting promise.\n\nThis class takes an optional `LoopInterface|null $loop` parameter that can be used to\npass the event loop instance to use for this object. You can use a `null` value\nhere in order to use the [default loop](https://github.com/reactphp/event-loop#loop).\nThis value SHOULD NOT be given unless you're sure you want to explicitly use a\ngiven event loop instance.\n\nYou can optionally pass additional\n[socket context options](https://www.php.net/manual/en/context.socket.php)\nto the constructor like this:\n\n```php\n$tcpConnector = new React\\Socket\\TcpConnector(null, [\n    'bindto' =\u003e '192.168.0.1:0'\n]);\n```\n\nNote that this class only allows you to connect to IP-port-combinations.\nIf the given URI is invalid, does not contain a valid IP address and port\nor contains any other scheme, it will reject with an\n`InvalidArgumentException`:\n\nIf the given URI appears to be valid, but connecting to it fails (such as if\nthe remote host rejects the connection etc.), it will reject with a\n`RuntimeException`.\n\nIf you want to connect to hostname-port-combinations, see also the following chapter.\n\n\u003e Advanced usage: Internally, the `TcpConnector` allocates an empty *context*\nresource for each stream resource.\nIf the destination URI contains a `hostname` query parameter, its value will\nbe used to set up the TLS peer name.\nThis is used by the `SecureConnector` and `DnsConnector` to verify the peer\nname and can also be used if you want a custom TLS peer name.\n\n#### HappyEyeBallsConnector\n\nThe `HappyEyeBallsConnector` class implements the\n[`ConnectorInterface`](#connectorinterface) and allows you to create plaintext\nTCP/IP connections to any hostname-port-combination. Internally it implements the \nhappy eyeballs algorithm from [`RFC6555`](https://tools.ietf.org/html/rfc6555) and \n[`RFC8305`](https://tools.ietf.org/html/rfc8305) to support IPv6 and IPv4 hostnames.\n\nIt does so by decorating a given `TcpConnector` instance so that it first\nlooks up the given domain name via DNS (if applicable) and then establishes the\nunderlying TCP/IP connection to the resolved target IP address.\n\nMake sure to set up your DNS resolver and underlying TCP connector like this:\n\n```php\n$dnsResolverFactory = new React\\Dns\\Resolver\\Factory();\n$dns = $dnsResolverFactory-\u003ecreateCached('8.8.8.8');\n\n$dnsConnector = new React\\Socket\\HappyEyeBallsConnector(null, $tcpConnector, $dns);\n\n$dnsConnector-\u003econnect('www.google.com:80')-\u003ethen(function (React\\Socket\\ConnectionInterface $connection) {\n    $connection-\u003ewrite('...');\n    $connection-\u003eend();\n});\n```\n\nSee also the [examples](examples).\n\nPending connection attempts can be cancelled by cancelling its pending promise like so:\n\n```php\n$promise = $dnsConnector-\u003econnect('www.google.com:80');\n\n$promise-\u003ecancel();\n```\n\nCalling `cancel()` on a pending promise will cancel the underlying DNS lookups\nand/or the underlying TCP/IP connection(s) and reject the resulting promise.\n\nThis class takes an optional `LoopInterface|null $loop` parameter that can be used to\npass the event loop instance to use for this object. You can use a `null` value\nhere in order to use the [default loop](https://github.com/reactphp/event-loop#loop).\nThis value SHOULD NOT be given unless you're sure you want to explicitly use a\ngiven event loop instance.\n\n\u003e Advanced usage: Internally, the `HappyEyeBallsConnector` relies on a `Resolver` to\nlook up the IP addresses for the given hostname.\nIt will then replace the hostname in the destination URI with this IP's and\nappend a `hostname` query parameter and pass this updated URI to the underlying\nconnector. \nThe Happy Eye Balls algorithm describes looking the IPv6 and IPv4 address for \nthe given hostname so this connector sends out two DNS lookups for the A and \nAAAA records. It then uses all IP addresses (both v6 and v4) and tries to \nconnect to all of them with a 50ms interval in between. Alterating between IPv6 \nand IPv4 addresses. When a connection is established all the other DNS lookups \nand connection attempts are cancelled.\n\n#### DnsConnector\n\nThe `DnsConnector` class implements the\n[`ConnectorInterface`](#connectorinterface) and allows you to create plaintext\nTCP/IP connections to any hostname-port-combination.\n\nIt does so by decorating a given `TcpConnector` instance so that it first\nlooks up the given domain name via DNS (if applicable) and then establishes the\nunderlying TCP/IP connection to the resolved target IP address.\n\nMake sure to set up your DNS resolver and underlying TCP connector like this:\n\n```php\n$dnsResolverFactory = new React\\Dns\\Resolver\\Factory();\n$dns = $dnsResolverFactory-\u003ecreateCached('8.8.8.8');\n\n$dnsConnector = new React\\Socket\\DnsConnector($tcpConnector, $dns);\n\n$dnsConnector-\u003econnect('www.google.com:80')-\u003ethen(function (React\\Socket\\ConnectionInterface $connection) {\n    $connection-\u003ewrite('...');\n    $connection-\u003eend();\n});\n```\n\nSee also the [examples](examples).\n\nPending connection attempts can be cancelled by cancelling its pending promise like so:\n\n```php\n$promise = $dnsConnector-\u003econnect('www.google.com:80');\n\n$promise-\u003ecancel();\n```\n\nCalling `cancel()` on a pending promise will cancel the underlying DNS lookup\nand/or the underlying TCP/IP connection and reject the resulting promise.\n\n\u003e Advanced usage: Internally, the `DnsConnector` relies on a `React\\Dns\\Resolver\\ResolverInterface`\nto look up the IP address for the given hostname.\nIt will then replace the hostname in the destination URI with this IP and\nappend a `hostname` query parameter and pass this updated URI to the underlying\nconnector.\nThe underlying connector is thus responsible for creating a connection to the\ntarget IP address, while this query parameter can be used to check the original\nhostname and is used by the `TcpConnector` to set up the TLS peer name.\nIf a `hostname` is given explicitly, this query parameter will not be modified,\nwhich can be useful if you want a custom TLS peer name.\n\n#### SecureConnector\n\nThe `SecureConnector` class implements the\n[`ConnectorInterface`](#connectorinterface) and allows you to create secure\nTLS (formerly known as SSL) connections to any hostname-port-combination.\n\nIt does so by decorating a given `DnsConnector` instance so that it first\ncreates a plaintext TCP/IP connection and then enables TLS encryption on this\nstream.\n\n```php\n$secureConnector = new React\\Socket\\SecureConnector($dnsConnector);\n\n$secureConnector-\u003econnect('www.google.com:443')-\u003ethen(function (React\\Socket\\ConnectionInterface $connection) {\n    $connection-\u003ewrite(\"GET / HTTP/1.0\\r\\nHost: www.google.com\\r\\n\\r\\n\");\n    ...\n});\n```\n\nSee also the [examples](examples).\n\nPending connection attempts can be cancelled by cancelling its pending promise like so:\n\n```php\n$promise = $secureConnector-\u003econnect('www.google.com:443');\n\n$promise-\u003ecancel();\n```\n\nCalling `cancel()` on a pending promise will cancel the underlying TCP/IP\nconnection and/or the SSL/TLS negotiation and reject the resulting promise.\n\nThis class takes an optional `LoopInterface|null $loop` parameter that can be used to\npass the event loop instance to use for this object. You can use a `null` value\nhere in order to use the [default loop](https://github.com/reactphp/event-loop#loop).\nThis value SHOULD NOT be given unless you're sure you want to explicitly use a\ngiven event loop instance.\n\nYou can optionally pass additional\n[SSL context options](https://www.php.net/manual/en/context.ssl.php)\nto the constructor like this:\n\n```php\n$secureConnector = new React\\Socket\\SecureConnector($dnsConnector, null, [\n    'verify_peer' =\u003e false,\n    'verify_peer_name' =\u003e false\n]);\n```\n\nBy default, this connector supports TLSv1.0+ and excludes support for legacy\nSSLv2/SSLv3. You can also explicitly choose the TLS version you\nwant to negotiate with the remote side:\n\n```php\n$secureConnector = new React\\Socket\\SecureConnector($dnsConnector, null, [\n    'crypto_method' =\u003e STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT\n]);\n```\n\n\u003e Advanced usage: Internally, the `SecureConnector` relies on setting up the\nrequired *context options* on the underlying stream resource.\nIt should therefor be used with a `TcpConnector` somewhere in the connector\nstack so that it can allocate an empty *context* resource for each stream\nresource and verify the peer name.\nFailing to do so may result in a TLS peer name mismatch error or some hard to\ntrace race conditions, because all stream resources will use a single, shared\n*default context* resource otherwise.\n\n#### TimeoutConnector\n\nThe `TimeoutConnector` class implements the\n[`ConnectorInterface`](#connectorinterface) and allows you to add timeout\nhandling to any existing connector instance.\n\nIt does so by decorating any given [`ConnectorInterface`](#connectorinterface)\ninstance and starting a timer that will automatically reject and abort any\nunderlying connection attempt if it takes too long.\n\n```php\n$timeoutConnector = new React\\Socket\\TimeoutConnector($connector, 3.0);\n\n$timeoutConnector-\u003econnect('google.com:80')-\u003ethen(function (React\\Socket\\ConnectionInterface $connection) {\n    // connection succeeded within 3.0 seconds\n});\n```\n\nSee also any of the [examples](examples).\n\nThis class takes an optional `LoopInterface|null $loop` parameter that can be used to\npass the event loop instance to use for this object. You can use a `null` value\nhere in order to use the [default loop](https://github.com/reactphp/event-loop#loop).\nThis value SHOULD NOT be given unless you're sure you want to explicitly use a\ngiven event loop instance.\n\nPending connection attempts can be cancelled by cancelling its pending promise like so:\n\n```php\n$promise = $timeoutConnector-\u003econnect('google.com:80');\n\n$promise-\u003ecancel();\n```\n\nCalling `cancel()` on a pending promise will cancel the underlying connection\nattempt, abort the timer and reject the resulting promise.\n\n#### UnixConnector\n\nThe `UnixConnector` class implements the\n[`ConnectorInterface`](#connectorinterface) and allows you to connect to\nUnix domain socket (UDS) paths like this:\n\n```php\n$connector = new React\\Socket\\UnixConnector();\n\n$connector-\u003econnect('/tmp/demo.sock')-\u003ethen(function (React\\Socket\\ConnectionInterface $connection) {\n    $connection-\u003ewrite(\"HELLO\\n\");\n});\n```\n\nConnecting to Unix domain sockets is an atomic operation, i.e. its promise will\nsettle (either resolve or reject) immediately.\nAs such, calling `cancel()` on the resulting promise has no effect.\n\n\u003e The [`getRemoteAddress()`](#getremoteaddress) method will return the target\n  Unix domain socket (UDS) path as given to the `connect()` method, prepended\n  with the `unix://` scheme, for example `unix:///tmp/demo.sock`.\n  The [`getLocalAddress()`](#getlocaladdress) method will most likely return a\n  `null` value as this value is not applicable to UDS connections here.\n\nThis class takes an optional `LoopInterface|null $loop` parameter that can be used to\npass the event loop instance to use for this object. You can use a `null` value\nhere in order to use the [default loop](https://github.com/reactphp/event-loop#loop).\nThis value SHOULD NOT be given unless you're sure you want to explicitly use a\ngiven event loop instance.\n\n#### FixedUriConnector\n\nThe `FixedUriConnector` class implements the\n[`ConnectorInterface`](#connectorinterface) and decorates an existing Connector\nto always use a fixed, preconfigured URI.\n\nThis can be useful for consumers that do not support certain URIs, such as\nwhen you want to explicitly connect to a Unix domain socket (UDS) path\ninstead of connecting to a default address assumed by an higher-level API:\n\n```php\n$connector = new React\\Socket\\FixedUriConnector(\n    'unix:///var/run/docker.sock',\n    new React\\Socket\\UnixConnector()\n);\n\n// destination will be ignored, actually connects to Unix domain socket\n$promise = $connector-\u003econnect('localhost:80');\n```\n\n## Install\n\nThe recommended way to install this library is [through Composer](https://getcomposer.org/).\n[New to Composer?](https://getcomposer.org/doc/00-intro.md)\n\nOnce released, this project will follow [SemVer](https://semver.org/).\nAt the moment, this will install the latest development version:\n\n```bash\ncomposer require react/socket:^3@dev\n```\n\nSee also the [CHANGELOG](CHANGELOG.md) for details about version upgrades.\n\nThis project aims to run on any platform and thus does not require any PHP\nextensions and supports running on PHP 7.1 through current PHP 8+.\nIt's *highly recommended to use the latest supported PHP version* for this project.\n\nLegacy PHP \u003c 7.3.3 (and PHP \u003c 7.2.15) suffers from a bug where feof() might\nblock with 100% CPU usage on fragmented TLS records.\nWe try to work around this by always consuming the complete receive\nbuffer at once to avoid stale data in TLS buffers. This is known to\nwork around high CPU usage for well-behaving peers, but this may\ncause very large data chunks for high throughput scenarios. The buggy\nbehavior can still be triggered due to network I/O buffers or\nmalicious peers on affected versions, upgrading is highly recommended.\n\nLegacy PHP \u003c 7.1.4 suffers from a bug when writing big\nchunks of data over TLS streams at once.\nWe try to work around this by limiting the write chunk size to 8192\nbytes for older PHP versions only.\nThis is only a work-around and has a noticable performance penalty on\naffected versions.\n\n## Tests\n\nTo run the test suite, you first need to clone this repo and then install all\ndependencies [through Composer](https://getcomposer.org/):\n\n```bash\ncomposer install\n```\n\nTo run the test suite, go to the project root and run:\n\n```bash\nvendor/bin/phpunit\n```\n\nThe test suite also contains a number of functional integration tests that rely\non a stable internet connection.\nIf you do not want to run these, they can simply be skipped like this:\n\n```bash\nvendor/bin/phpunit --exclude-group internet\n```\n\n## License\n\nMIT, see [LICENSE file](LICENSE).\n","funding_links":["https://github.com/sponsors/reactphp","https://github.com/sponsors/clue","https://github.com/sponsors/WyriHaximus","https://opencollective.com/reactphp"],"categories":["PHP"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freactphp%2Fsocket","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freactphp%2Fsocket","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freactphp%2Fsocket/lists"}