{"id":30023557,"url":"https://github.com/bloatless/php-websocket","last_synced_at":"2026-03-01T06:09:28.417Z","repository":{"id":2002376,"uuid":"2591294","full_name":"bloatless/php-websocket","owner":"bloatless","description":"Simple WebSocket server implemented in PHP.","archived":false,"fork":false,"pushed_at":"2022-10-22T01:31:37.000Z","size":665,"stargazers_count":591,"open_issues_count":5,"forks_count":197,"subscribers_count":51,"default_branch":"master","last_synced_at":"2026-01-25T15:04:06.724Z","etag":null,"topics":["php","websocket-server","websockets"],"latest_commit_sha":null,"homepage":"https://bloatless.org","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/bloatless.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2011-10-17T11:21:55.000Z","updated_at":"2025-09-29T21:47:27.000Z","dependencies_parsed_at":"2022-08-06T11:16:43.822Z","dependency_job_id":null,"html_url":"https://github.com/bloatless/php-websocket","commit_stats":null,"previous_names":["nekudo/php-websocket","lemmingzshadow/php-websocket"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/bloatless/php-websocket","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bloatless%2Fphp-websocket","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bloatless%2Fphp-websocket/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bloatless%2Fphp-websocket/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bloatless%2Fphp-websocket/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bloatless","download_url":"https://codeload.github.com/bloatless/php-websocket/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bloatless%2Fphp-websocket/sbom","scorecard":{"id":243610,"data":{"date":"2025-08-11","repo":{"name":"github.com/bloatless/php-websocket","commit":"4de006c126644f8ff868f4249ecb648b207cb697"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.6,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":4,"reason":"Found 7/16 approved changesets -- score normalized to 4","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 21 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-17T07:05:43.445Z","repository_id":2002376,"created_at":"2025-08-17T07:05:43.445Z","updated_at":"2025-08-17T07:05:43.445Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29962004,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T05:59:08.471Z","status":"ssl_error","status_checked_at":"2026-03-01T05:58:04.208Z","response_time":124,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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","websocket-server","websockets"],"created_at":"2025-08-06T05:02:26.274Z","updated_at":"2026-03-01T06:09:28.408Z","avatar_url":"https://github.com/bloatless.png","language":"PHP","funding_links":[],"categories":["PHP"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://bloatless.org/img/logo.svg\" width=\"60px\" height=\"80px\"\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003eBloatless PHP WebSockets\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n    Simple WebSocket server implemented in PHP.\n\u003c/p\u003e\n\n- [Installation](#installation)\n    - [Requirements](#requirements)\n    - [Installation procedure](#installation-procedure)\n- [Usage](#usage)\n    - [Server](#server)\n    - [Applications](#applications)\n    - [Timers](#timers)\n    - [Push-Client (IPC)](#push-client-ipc)\n    - [Client (Browser/JS)](#client-browserjs)\n- [Intended use and limitations](#intended-use-and-limitations)\n- [Alternatives](#alternatives)\n- [License](#license)\n\n## Installation\n\n### Requirements\n\n* PHP \u003e= 7.4\n* ext-json\n* ext-sockets\n\n### Installation procedure\n\nInstall the package using composer:\n\n`composer require bloatless/php-websocket`\n\n## Usage\n\n### Server\n\nAfter downloading the sourcecode to your machine, you need some code to actually put your websocket server together.\nHere is a basic exmaple:\n```php\n\u003c?php\n\n// require necessary files here\n\n// create new server instance\n$server = new \\Bloatless\\WebSocket\\Server('127.0.0.1', 8000, '/tmp/phpwss.sock');\n\n// server settings\n$server-\u003esetMaxClients(100);\n$server-\u003esetCheckOrigin(false);\n$server-\u003esetAllowedOrigin('example.com');\n$server-\u003esetMaxConnectionsPerIp(20);\n\n// add your applications\n$server-\u003eregisterApplication('status', \\Bloatless\\WebSocket\\Application\\StatusApplication::getInstance());\n$server-\u003eregisterApplication('chat', \\Bloatless\\WebSocket\\Examples\\Application\\Chat::getInstance());\n\n// start the server\n$server-\u003erun();\n```\n\nAssuming this code is in a file called `server.php` you can then start your server with the following command:\n\n```shell\nphp server.php\n```\n\nThe websocket server will then listen for new connections on the provided host and port. By default, this will be\n`localhost:8000`.\n\nThis repositoy also includes a working example in [examples/server.php](examples/server.php)\n\n### Applications\n\nThe websocket server itself handles connections but is pretty useless without any addional logic. This logic is added\nby applications. In the example above two applications are added to the server: `status` and `chat`.\n\nThe most important methods in your application will be:\n\n```php\ninterface ApplicationInterface\n{\n    public function onConnect(Connection $connection): void;\n\n    public function onDisconnect(Connection $connection): void;\n\n    public function onData(string $data, Connection $client): void;\n\n    public function onIPCData(array $data): void;\n}\n```\n\n`onConnect` and `onDisconnect` can be used to keep track of all the clients connected to your application. `onData` will\nbe called whenever the websocket server receives new data from one of the clients connected to the application. \n`onIPCData` will be called if data is provided by another process on your machine. (See [Push-Client (IPC)](#push-client-ipc))\n\nA working example of an application can be found in [examples/Application/Chat.php](examples/Application/Chat.php)\n\n### Timers\n\nA common requirement for long-running processes such as a websocket server is to execute tasks periodically. This can\nbe done using timers. Timers can execute methods within your server or application periodically. Here is an example:\n\n```php\n$server = new \\Bloatless\\WebSocket\\Server('127.0.0.1', 8000, '/tmp/phpwss.sock');\n$chat = \\Bloatless\\WebSocket\\Examples\\Application\\Chat::getInstance();\n$server-\u003eaddTimer(5000, function () use ($chat) {\n    $chat-\u003esomeMethod();\n});\n$server-\u003eregisterApplication('chat', $chat);\n```\n\nThis example would call the method `someMethod` within your chat application every 5 seconds.\n\n### Push-Client (IPC)\n\nIt is often required to push data into the websocket-server process from another application. Let's assume you run a\nwebsite containing a chat and an area containing news or a blog. Now every time a new article is published in your blog\nyou want to notify all users currently in your chat. To achieve this you somehow need to push data from your blog\nlogic into the websocket server. This is where the Push-Client comes into play.\n\nWhen starting the websocket server, it opens a unix-domain-socket and listens for new messages. The Push-Client can\nthen be used to send these messages. Here is an example:\n\n```php\n$pushClient = new \\Bloatless\\WebSocket\\PushClient('//tmp/phpwss.sock');\n$pushClient-\u003esendToApplication('chat', [\n    'action' =\u003e 'echo',\n    'data' =\u003e 'New blog post was published!',\n]);\n```\n\nThis code pushes data into your running websocket-server process. In this case the `echo` method within the\nchat-application is called and it sends the provided message to all connected clients.\n\nYou can find the full working example in: [examples/push.php](examples/push.php)\n\n**Important Hint:** Push messages cannot be larger than 64kb!\n\n### Client (Browser/JS)\n\nEverything above this point was related to the server-side of things. But how to connect to the server from your browser?\n\nHere is a simple example:\n\n```html\n\u003cscript\u003e\n // connect to chat application on server\nlet serverUrl = 'ws://127.0.0.1:8000/chat';\nlet socket = new WebSocket(serverUrl);\n\n// log new messages to console\nsocket.onmessage = (msg) =\u003e {\n    let response = JSON.parse(msg.data);\n    console.log(response.data);\n};\n\u003c/script\u003e\n```\n\nThis javascript connects to the chat application on your server and prints all incoming messages into the console.\n\nA better example of the chat client can be found in: [examples/public/chat.html](examples/public/chat.html)\n\n## Intended use and limitations\n\nThis project was mainly built for educational purposes. The code is relatively simple and easy to understand. This\nserver was **not tested in production**, so I strongly recommend not to use it in a live project. It should be totally\nfine for small educational projects or internal tools, but most probably will not handle huge amounts of traffic or\nconnections very well.\n\nAlso, some \"features\" are missing by design:\n\n* SSL is not supported. If required, you can use a reverse proxy like nginx.\n* Binary messages are not supported.\n* A lot of other stuff I did not even realize ;)\n\nIn case you need a more \"robust\" websocket server written in PHP, please have a look at the excellent alternatives\nlisted below.\n\n## Alternatives\n\n* [Ratchet](https://github.com/ratchetphp/Ratchet)\n* [Wrench](https://github.com/varspool/Wrench)\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbloatless%2Fphp-websocket","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbloatless%2Fphp-websocket","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbloatless%2Fphp-websocket/lists"}