{"id":13828085,"url":"https://github.com/amphp/socket","last_synced_at":"2025-04-08T10:23:23.882Z","repository":{"id":19244010,"uuid":"22479171","full_name":"amphp/socket","owner":"amphp","description":"Non-blocking socket and TLS functionality for PHP based on Amp.","archived":false,"fork":false,"pushed_at":"2024-04-21T14:41:57.000Z","size":1093,"stargazers_count":214,"open_issues_count":2,"forks_count":39,"subscribers_count":14,"default_branch":"2.x","last_synced_at":"2024-05-15T17:49:16.656Z","etag":null,"topics":["amphp","async","client","io","non-blocking","php","server","socket","ssl","tcp","tls","udp","unix"],"latest_commit_sha":null,"homepage":"https://amphp.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/amphp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","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}},"created_at":"2014-07-31T17:57:14.000Z","updated_at":"2024-06-18T10:58:30.926Z","dependencies_parsed_at":"2024-01-18T05:14:54.287Z","dependency_job_id":"3eb01fb5-793d-490a-b1cc-4b9c523f798a","html_url":"https://github.com/amphp/socket","commit_stats":{"total_commits":483,"total_committers":17,"mean_commits":28.41176470588235,"dds":0.5238095238095238,"last_synced_commit":"70a72fb8b4fbc0117b65c6fb927651ecb8a4b325"},"previous_names":[],"tags_count":69,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amphp%2Fsocket","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amphp%2Fsocket/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amphp%2Fsocket/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amphp%2Fsocket/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/amphp","download_url":"https://codeload.github.com/amphp/socket/tar.gz/refs/heads/2.x","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247820521,"owners_count":21001506,"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":["amphp","async","client","io","non-blocking","php","server","socket","ssl","tcp","tls","udp","unix"],"created_at":"2024-08-04T09:02:31.716Z","updated_at":"2025-04-08T10:23:23.863Z","avatar_url":"https://github.com/amphp.png","language":"PHP","readme":"# amphp/socket\n\nAMPHP is a collection of event-driven libraries for PHP designed with fibers and concurrency in mind.\n`amphp/socket` is a library for establishing and encrypting non-blocking sockets.\nIt provides a socket abstraction for clients and servers.\nIt abstracts the really low levels of non-blocking streams in PHP.\n\n[![Latest Release](https://img.shields.io/github/release/amphp/socket.svg?style=flat-square)](https://github.com/amphp/socket/releases)\n[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://github.com/amphp/socket/blob/master/LICENSE)\n\n## Installation\n\nThis package can be installed as a [Composer](https://getcomposer.org/) dependency.\n\n```bash\ncomposer require amphp/socket\n```\n\n## Requirements\n\n`amphp/socket` heavily relies on `amphp/byte-stream`, specifically its `ReadableStream` and `WritableStream` interfaces.\n\n## Connecting to a Server\n\n`amphp/socket` allows clients to connect to servers via TCP, UDP, or Unix domain sockets.\nYou can establish a socket connection using `Amp\\Socket\\connect()`.\nIt will automatically resolve DNS names and retries other IPs if a connection fails and multiple IPs are available.\n\n```php\n// You can customize connect() options using ConnectContext\n$connectContext = (new Amp\\Socket\\ConnectContext)\n        -\u003ewithConnectTimeout(5);\n\n// You can optionally pass a Cancellation object to cancel a pending connect() operation\n$deferredCancellation = new Amp\\DeferredCancellation();\n\n$socket = connect('amphp.org:80', $connectContext, $deferredCancellation-\u003egetCancellation());\n```\n\n### Encrypted Connections / TLS\n\nIf you want to connect via TLS, use `Amp\\Socket\\connectTls()` instead or call `$socket-\u003esetupTls()` on the returned socket.\n\n### Handling Connections\n\n`Socket` implements `ReadableStream` and `WritableStream`, so everything from [`amphp/byte-stream`](https://v3.amphp.org/byte-stream) applies for receiving and sending data.\n\n```php\n#!/usr/bin/env php\n\u003c?php // basic (and dumb) HTTP client\n\nrequire __DIR__ . '/../vendor/autoload.php';\n\n// This is a very simple HTTP client that just prints the response without parsing.\n// league/uri required for this example.\n\nuse Amp\\ByteStream;\nuse Amp\\Socket\\ClientTlsContext;\nuse Amp\\Socket\\ConnectContext;\nuse League\\Uri\\Http;\nuse function Amp\\Socket\\connect;\nuse function Amp\\Socket\\connectTls;\n\n$stdout = ByteStream\\getStdout();\n\nif (\\count($argv) !== 2) {\n    $stdout-\u003ewrite('Usage: examples/simple-http-client.php \u003curl\u003e' . PHP_EOL);\n    exit(1);\n}\n\n$uri = Http::createFromString($argv[1]);\n$host = $uri-\u003egetHost();\n$port = $uri-\u003egetPort() ?? ($uri-\u003egetScheme() === 'https' ? 443 : 80);\n$path = $uri-\u003egetPath() ?: '/';\n\n$connectContext = (new ConnectContext)\n        -\u003ewithTlsContext(new ClientTlsContext($host));\n\n$socket = $uri-\u003egetScheme() === 'http'\n        ? connect($host . ':' . $port, $connectContext)\n        : connectTls($host . ':' . $port, $connectContext);\n\n$socket-\u003ewrite(\"GET {$path} HTTP/1.1\\r\\nHost: $host\\r\\nConnection: close\\r\\n\\r\\n\");\n\nByteStream\\pipe($socket, $stdout);\n```\n\n## Server\n\n`amphp/socket` allows listening for incoming TCP connections as well as connections via Unix domain sockets.\nIt defaults to secure TLS settings if you decide to enable TLS.\n\n### Listening and Accepting Connections\n\nUse `Amp\\Socket\\Socket\\listen()` to listen on a port or unix domain socket.\nIt's a wrapper around `stream_socket_server` that gives useful error message on failures via exceptions.\n\nOnce you're listening, accept clients using `Server::accept()`.\nIt returns a `Socket` that returns once a new client has been accepted.\nIt's usually called within a `while` loop:\n\n```php\n$server = Socket\\listen(\"tcp://127.0.0.1:1337\");\n\nwhile ($client = $server-\u003eaccept()) {\n    // You shouldn't spend too much time here, because that blocks accepting another client, so we use async():\n    async(function () use ($client) {\n        // Handle client connection here\n    });\n}\n```\n\n### Handling Connections\n\n`Socket` implements `ReadableStream` and `WritableStream`, so everything from [`amphp/byte-stream`](https://v3.amphp.org/byte-stream) applies for receiving and sending data.\nIt's best to handle clients in their own coroutine, while letting the server accept all clients as soon as there are new clients.\n\n```php\n#!/usr/bin/env php\n\u003c?php // basic (and dumb) HTTP server\n\nrequire __DIR__ . '/../vendor/autoload.php';\n\n// This is a very simple HTTP server that just prints a message to each client that connects.\n// It doesn't check whether the client sent an HTTP request.\n\n// You might notice that your browser opens several connections instead of just one,\n// even when only making one request.\n\nuse Amp\\Socket;\nuse function Amp\\async;\n\n$server = Socket\\listen('127.0.0.1:0');\n\necho 'Listening for new connections on ' . $server-\u003egetAddress() . ' ...' . PHP_EOL;\necho 'Open your browser and visit http://' . $server-\u003egetAddress() . '/' . PHP_EOL;\n\nwhile ($socket = $server-\u003eaccept()) {\n    async(function () use ($socket) {\n        $address = $socket-\u003egetRemoteAddress();\n        $ip = $address-\u003egetHost();\n        $port = $address-\u003egetPort();\n\n        echo \"Accepted connection from {$address}.\" . PHP_EOL;\n\n        $body = \"Hey, your IP is {$ip} and your local port used is {$port}.\";\n        $bodyLength = \\strlen($body);\n\n        $socket-\u003ewrite(\"HTTP/1.1 200 OK\\r\\nConnection: close\\r\\nContent-Length: {$bodyLength}\\r\\n\\r\\n{$body}\");\n        $socket-\u003eend();\n    });\n}\n```\n\n### Closing Connections\n\nOnce you're done with a client, close the connection using `Socket::close()`.\nIf you want to wait for all data to be successfully written before closing the connection, use `Socket::end()`.\nSee above for an example.\n\n### Server Address\n\nSometimes you don't know the address the server is listening on, e.g. because you listed to `tcp://127.0.0.1:0`, which assigns a random free port. You can use `Server::getAddress()` to get the address the server is bound to.\n\n### Server Shutdown\n\nOnce you're done with the server socket, close the socket.\nThat means, the server won't listen on the specified location anymore.\nUse `Server::close()` to close the server socket.\n\n### Encrypted Connections / TLS\n\nAs already mentioned in the documentation for `Amp\\Socket\\Socket\\listen()`, you need to enable TLS manually after accepting connections.\nFor a TLS server socket, you listen on the `tcp://` protocol on a specified address.\nAfter accepting clients, call `$socket-\u003esetupTls()` where `$socket` is the socket returned from `SocketServer::accept()`.\n\n\u003e **Warning**\n\u003e Any data transmitted before `Socket::setupTls()` completes will be transmitted in clear text.\n\u003e Don't attempt to read from the socket or write to it manually.\n\u003e Doing so will read the raw TLS handshake data that's supposed to be read by OpenSSL.\n\n#### Self-Signed Certificates\n\nThere's no option to allow self-signed certificates in `ClientTlsContext` since it is no more secure than disabling peer verification.\nTo safely use a self-signed certificate, disable peer verification and require fingerprint verification of the certificate using `ClientTlsContext::withPeerFingerprint()`.\n\n## Security\n\nIf you discover any security related issues, please email [`me@kelunik.com`](mailto:me@kelunik.com) instead of using the issue tracker.\n\n## License\n\nThe MIT License (MIT). Please see [`LICENSE`](./LICENSE) for more information.\n","funding_links":[],"categories":["Socket","PHP"],"sub_categories":["Tunnel"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famphp%2Fsocket","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Famphp%2Fsocket","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famphp%2Fsocket/lists"}