{"id":28507635,"url":"https://github.com/a-drew/laravel-sockets","last_synced_at":"2026-04-14T18:32:57.706Z","repository":{"id":57081827,"uuid":"155224864","full_name":"a-drew/laravel-sockets","owner":"a-drew","description":"A Sockets Management Provider built for Laravel 5, based on the Laravel's Database Provider","archived":false,"fork":false,"pushed_at":"2019-05-11T17:54:00.000Z","size":9,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-08-02T08:05:41.864Z","etag":null,"topics":["api-wrapper","laravel","php","socket","tcp-client","tcp-socket","udp-socket"],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/a-drew.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-10-29T14:23:10.000Z","updated_at":"2021-06-11T19:55:26.000Z","dependencies_parsed_at":"2022-08-24T14:58:18.011Z","dependency_job_id":null,"html_url":"https://github.com/a-drew/laravel-sockets","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/a-drew/laravel-sockets","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a-drew%2Flaravel-sockets","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a-drew%2Flaravel-sockets/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a-drew%2Flaravel-sockets/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a-drew%2Flaravel-sockets/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/a-drew","download_url":"https://codeload.github.com/a-drew/laravel-sockets/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a-drew%2Flaravel-sockets/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31810737,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-14T18:05:02.291Z","status":"ssl_error","status_checked_at":"2026-04-14T18:05:01.765Z","response_time":153,"last_error":"SSL_read: 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":["api-wrapper","laravel","php","socket","tcp-client","tcp-socket","udp-socket"],"created_at":"2025-06-08T20:40:50.314Z","updated_at":"2026-04-14T18:32:57.678Z","avatar_url":"https://github.com/a-drew.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# About laravel-sockets\n\nThis project is a good place to start for developing an application that is requires \nto retrieve or send data via UDP/TCP Sockets .\n\n## Requirements\n\n - PHP \u003e= 7.0\n - Laravel \u003e= 5.5 \n\n## Quick Install\n```\n$ composer require wor/sockets:\"^1.0\"\n```\nOR \n\nadd `wor/sockets:\"^1.0\"` to your `require` list in the `composer.json` file.\n\n#### Service Provider \u0026 Facade (Optional on Laravel 5.5+)\nRegister provider and facade on your config/app.php file.\n```\n'providers' =\u003e [\n    ...,\n    Wor\\Sockets\\SocketsServiceProvider::class,\n]\n\n'aliases' =\u003e [\n    ...,\n    'Sockets' =\u003e Wor\\Sockets\\SocketsFacade::class,\n]\n```\n\n#### Configuration (Optional)\n```\n$ php artisan vendor:publish --provider=\"Wor\\Sockets\\SocketsServiceProvider\"\n```\n\n## Debugging Mode\nTo enable debugging mode, just set SOCKET_DEBUG=true and the package will echo the raw payload being sent and received across Sockets.\n\nIMPORTANT: Please make sure that SOCKET_DEBUG is set to false when your app is on production.\n\n## Usage\n### Basic Usage\n\n1. Add the default socket remote to your .env file\n    ```\n    ...\n    SOCKET_CONNECTION=default\n    SOCKET_HOST=\u003cYOUR IP HERE\u003e\n    SOCKET_PORT=\u003cYOUR PORT HERE\u003e\n    SOCKET_PROTOCOL=tcp\n    SOCKET_DEBUG=true\n    ...\n    ```\n\n2. In Laravel or during a tinker session\n    ```\n    Sockets::write('Message');\n    $response = Sockets::read(); //returns the string response from the socket.\n    ```\n\n### Intended Usage\nThis package is intended to be extended. There are two basic concepts at play here : Sockets \u0026 Requests.\n\n#### Sockets\nSockets are the basic communication layer. They should are meant to be extended to \ninclude any frame wrapping or encoding that you may want to use or that the receiving \nservice expects. \n\nThey should extend the base Socket class and implement the SocketInterface. \n\nIn short you should implement the read \u0026 write methods to match your expected I/O.\n\n```\n\u003c?php\n\nnamespace Wor\\Salto\\Connectors;\n\nuse Wor\\Sockets\\Connectors\\Socket;\nuse Wor\\Sockets\\Connectors\\SocketInterface;\n\nclass SaltoSocket extends Socket implements SocketInterface\n{\n    /**\n     * @var string protocol identifier\n     */\n    public $protocol = 'STP';\n\n    /**\n     * @var string version of the salto protocol\n     */\n    public $version = '00';\n\n    /**\n     * Craft the ship packet header\n     * @return string header\n     */\n    public function getHeader()\n    {\n        return \"$this-\u003eprotocol/$this-\u003eversion/$this-\u003elength/\";\n    }\n\n    /**\n     * Salto SHIP protocol based write method   **overloads base write() method**\n     * Wraps the message in the expected xml format and creates\n     *\n     * @param string $message to send\n     *\n     * @return bool success\n     */\n    public function write(string $message): bool\n    {\n        $data = '\u003c?xml version=\"1.0\" encoding=\"ISO-8859-1\"?\u003e\u003cRequestCall\u003e'.$message.'\u003c/RequestCall\u003e';\n        $this-\u003elength = \\strlen($data); //setups the length displayed in the header\n        return parent::write($this-\u003egetHeader().$data);\n    }\n\n    /**\n     * Salto SHIP protocol based read method   **overloads base write() method**\n     * Reads header and uses expected message length to quickly load the response\n     *\n     * @param int $timeout in seconds\n     *\n     * @return string|null received message\n     */\n    public function read($timeout = 25): string\n    {\n        $this-\u003eprotocol = stream_get_line($this-\u003esocket,4, '/');\n        $this-\u003eversion = stream_get_line($this-\u003esocket,3, '/');\n        $this-\u003elength = (int) stream_get_line($this-\u003esocket,8, '/');\n\n        stream_set_timeout($this-\u003esocket, $timeout);\n        $read = stream_get_contents($this-\u003esocket, $this-\u003elength);\n        return $read;\n    }\n}\n```\n\n\n\n#### Requests\nRequests are meant to encapsulate an action that is performed. They should match the endpoints\nprovided by the service you're working with. Think of them as database transactions. Once you\nsetup the payload and make the request it performs a write and read on the provided socket and\nreturns a parsed result. \n\nRequests extend the base Request class and implement the RequestInterface.\n\n```\n\u003c?php\n\nnamespace Wor\\Salto\\Requests;\n\nuse Wor\\Salto\\Connectors\\SaltoSocket as Socket;\nuse Wor\\Salto\\Exceptions\\EncoderConnectionException;\nuse Wor\\Salto\\Exceptions\\EncoderTimeoutException;\nuse Wor\\Salto\\Exceptions\\XMLDocumentException;\nuse Wor\\Salto\\Exceptions\\OperationNotSupportedException;\nuse Wor\\Salto\\Exceptions\\SaltoException;\nuse Wor\\Sockets\\Requests\\Request;\nuse Wor\\Sockets\\Requests\\RequestInterface;\nuse Illuminate\\Support\\Collection;\n\nclass SaltoRequest extends Request implements RequestInterface {\n\n    /**\n     * @var string ship protocol RequestName\n     */\n    protected $name;\n\n    /**\n     * @var array of parameters\n     */\n    protected $params = [];\n\n    /**\n     * @var string json encoded response\n     */\n    protected $json;\n\n    /**\n     * @var Collection final response object\n     */\n    protected $collection;\n\n    /**\n     * Salto Request constructor.\n     *\n     * @param Socket        $socket\n     * @param string|array  $params\n     * @param string        $name\n     */\n    public function __construct(Socket $socket, $params = [], $name = null)\n    {\n        $this-\u003eboot();\n        parent::__construct($socket);\n\n        if (\\is_array($params)) {\n            $this-\u003esetParams($params);\n        } elseif (\\is_string($params)) {\n            // Allow to ignore parameters array and pass the name of the request directly\n            $name = $params;\n        }\n        if($name !== null) { // Avoid overriding self defined default request name\n            $this-\u003esetName($name);\n        }\n        $this-\u003ebeforePayload();\n        $this-\u003eprepPayload();\n    }\n\n    /**\n     * Generic boot method to be changed in subclasses\n     * ran before the rest of the constructor\n     */\n    public function boot(): void\n    {\n        //\n    }\n\n    /**\n     * Generic boot method to be changed in subclasses\n     * ran before setting up the payload\n     */\n    public function beforePayload(): void\n    {\n        //\n    }\n\n    /**\n     * @param string $name\n     */\n    public function setName($name): void\n    {\n        $this-\u003ename = $name;\n    }\n\n    /**\n     * @param array $params\n     */\n    public function setParams($params): void\n    {\n        $this-\u003eparams = $params;\n    }\n\n    /**\n     * Return formatted response of request\n     *\n     * @return Collection|mixed\n     */\n    public function getResponse()\n    {\n        //$this-\u003echeckException();\n        return new Collection($this-\u003ecollection);\n    }\n\n    /**\n     * Parse name and params into xml payload\n     */\n    private function prepPayload(): void\n    {\n        $header = '\u003cRequestName\u003e'.$this-\u003ename.'\u003c/RequestName\u003e';\n        $params = '\u003cParams\u003e';\n\n        foreach ($this-\u003eparams as $key =\u003e $value) {\n            if ($key !== null \u0026\u0026 $value !== null) {\n                // cast boolean values to int for output to ship xml\n                !\\is_bool($value) ?: $value = (int) $value;\n\n                // Output associative array as an ship parameter entry\n                $params .= '\u003c'.$key.'\u003e'.$value.'\u003c/'.$key.'\u003e';\n            }\n        }\n        $this-\u003epayload = $header.$params.'\u003c/Params\u003e';\n    }\n\n    /**\n     * Run the request on socket and return the response\n     *\n     * @return bool|mixed false if failed else return formatted response\n     *\n     * @throws SaltoException\n     */\n    public function make()\n    {\n        if($this-\u003esocket !== null \u0026\u0026 $this-\u003esocket-\u003ewrite($this-\u003epayload)) {\n            $this-\u003eresponse = $this-\u003esocket-\u003eread();\n            $xml = simplexml_load_string($this-\u003eresponse);\n            $this-\u003ejson = json_encode($xml);\n            $this-\u003ecollection = collect(json_decode($this-\u003ejson, true));\n            $this-\u003echeckException();\n            return $this-\u003egetResponse();\n        }\n        return false;\n    }\n\n    /**\n     * Check the response for known ship protocol exceptions\n     *\n     * @return bool\n     *\n     * @throws SaltoException\n     */\n    public function checkException(): bool\n    {\n        if($this-\u003ecollection-\u003ehas('Exception')) {\n            $exception = $this-\u003ecollection['Exception'];\n\n            switch ( (int) $exception['Code']) {\n                case 4:\n                    throw new OperationNotSupportedException($exception['Message']);\n                    break;\n                case 12:\n                    throw new XMLDocumentException($exception['Message']);\n                    break;\n                case 401:\n                    throw new EncoderConnectionException($exception['Message']);\n                    break;\n                case 403:\n                    throw new EncoderTimeoutException($exception['Message']);\n                    break;\n                default:\n                    throw new SaltoException($exception['Message'], $exception['Code']);\n                    break;\n            }\n        }\n        return false;\n    }\n}\n```\n\nThen you are free to instantiate new requests and run them against your socket service.\n\n```\n$socket = Socket::socket('default');\n$params = []; //the parameters you want to send through\n$request = new SaltoRequest($socket, $params, 'GetInfo');\n$response = $request-\u003eget();\n```\n\nIn fact you can take it one step further and create action requests based on your new genetic service request.\n\n```\n$socket = Socket::socket('default');\n$params = []; //the parameters you want to send through\n$request = new GetInfoRequest($socket, $params);\n$response = $request-\u003eget();\n```\n```\n\u003c?php\n\nnamespace Wor\\Salto\\Requests;\n\nuse Wor\\Salto\\Requests\\SaltoRequest;\n\nclass GetInfoRequest extends SaltoRequest {\n\n        protected $name = 'GetInfo'; //overload the default name with the request type\n    \n        public function getResponse() //overload the default getResponse action.\n        {\n            $response = parent::getResponse();\n            //Manipulate the response collection as you see fit. maybe match to domain models..\n            return $response;\n        }\n}\n```\n\n### Any Issues?\nIf you discover any errors feel free to report them in the issue tracker.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fa-drew%2Flaravel-sockets","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fa-drew%2Flaravel-sockets","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fa-drew%2Flaravel-sockets/lists"}