{"id":18883917,"url":"https://github.com/sfcod/socketio","last_synced_at":"2025-03-16T19:11:32.230Z","repository":{"id":57048422,"uuid":"122215724","full_name":"sfcod/socketio","owner":"sfcod","description":null,"archived":false,"fork":false,"pushed_at":"2024-09-12T08:19:19.000Z","size":64,"stargazers_count":25,"open_issues_count":1,"forks_count":8,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-10T09:48:36.949Z","etag":null,"topics":["asy","bundle","php","socket","socket-io","symfony","symfony-bundle","symfony-socket-io"],"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/sfcod.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-02-20T15:21:55.000Z","updated_at":"2024-09-12T08:19:23.000Z","dependencies_parsed_at":"2024-09-12T18:07:19.058Z","dependency_job_id":null,"html_url":"https://github.com/sfcod/socketio","commit_stats":{"total_commits":41,"total_committers":3,"mean_commits":"13.666666666666666","dds":"0.41463414634146345","last_synced_commit":"4e6441e13757239069e65e0b6c9462a502e5bda1"},"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sfcod%2Fsocketio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sfcod%2Fsocketio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sfcod%2Fsocketio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sfcod%2Fsocketio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sfcod","download_url":"https://codeload.github.com/sfcod/socketio/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243918600,"owners_count":20368745,"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":["asy","bundle","php","socket","socket-io","symfony","symfony-bundle","symfony-socket-io"],"created_at":"2024-11-08T07:09:49.149Z","updated_at":"2025-03-16T19:11:32.154Z","avatar_url":"https://github.com/sfcod.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"Symfony Socket.io bundle\n========================\n\n[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/sfcod/socketio/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/sfcod/socketio/?branch=master)[![Code Climate](https://codeclimate.com/github/sfcod/socketio/badges/gpa.svg)](https://codeclimate.com/github/sfcod/socketio)\n\nUse all power of socket.io in your Symfony project.\n\n#### Config\n\n###### Install node, after install npm\n```bash\n    npm install --prefix ./vendor/sfcod/socketio/Server\n```\n\n```yaml\nservices:\n    App\\SocketIo\\:\n        resource: '../src/SocketIo/*'\n        tags: ['sfcod.socketio.event']\n        # If you want override default JoinHandler/LeaveHandler. For example, add some condition for join/leave a room.\n        exclude:\n            - '../src/SocketIo/JoinHandler.php' # Optional\n            - '../src/SocketIo/LeaveHandler.php' # Optional\n        \n  \n    # If you want override default JoinHandler\n    SfCod\\SocketIoBundle\\Service\\JoinHandler:\n        class: App\\SocketIo\\JoinHandler\n        tags: ['sfcod.socketio.event']\n\n    # If you want override default LeaveHandler\n    SfCod\\SocketIoBundle\\Service\\LeaveHandler:\n        class: App\\SocketIo\\LeaveHandler\n        tags: ['sfcod.socketio.event']\n```\nExtend base class or use SF decorator. Ovveride fire or handle methods if it needs.\n```php\nnamespace App\\SocketIo;\n\nuse SfCod\\SocketIoBundle\\Service\\JoinHandler as JoinHandlerBase;\n\nclass JoinHandler extends JoinHandlerBase\n{\n    public function fire(): array\n    {\n        // Some additional logic here.\n        // ... \n        return array_merge_recursive(parent::fire(), [\n            'key' =\u003e 'value'\n        ]);\n    }\n}\n```\n\n###### Process Middlewares\nIf you use doctrine, then you can connect \"doctrine reconnect\", then it will be reconnect for each process.\n```yaml\nsfcod_socketio:\n    processMiddlewares:\n        - 'SfCod\\SocketIoBundle\\Middleware\\Process\\DoctrineReconnect'\n\n```\n\n```dotenv\n###\u003e socketio config ###\nSOCKET_IO_WS_SERVER=localhost:1358\nSOCKET_IO_WS_CLIENT=localhost:1358\nSOCKET_IO_SSL='' || '{\"key\":\"path to key\", \"cert\":\"path to cert\"}'\nSOCKET_IO_NSP=redis\n###\u003c socketio config ###\n```\n\nJWT token auth. Put SOCKET_IO_AUTH_TOKEN_PATH OR SOCKET_IO_AUTH_TOKEN_VALUE\n```dotenv\n#Public jwt token key path (Will be join with base path)\nSOCKET_IO_AUTH_TOKEN_PATH='/config/jwt/public.pem'\n#Public key value\nSOCKET_IO_AUTH_TOKEN_VALUE='public key value'\n#You can change token name. Default name is 'token'\nSOCKET_IO_AUTH_TOKEN_NAME='token'\n```\n```js\n    var socket = io('{your_host_address}:1367/notifications',  {\n        query: {\n            token: 'yourTokenHere',\n        },\n     });\n```\n\n#### Usage\n\n###### Start nodejs server\n```bash\n    php bin/console socket-io:node-js-server\n```\n###### Start php server\n```bash\n    php bin/console socket-io:php-server\n```\n\n###### Create publisher from server to client\n```php\n    use SfCod\\SocketIoBundle\\Events\\EventInterface;\n    use SfCod\\SocketIoBundle\\Events\\EventPublisherInterface;\n    use SfCod\\SocketIoBundle\\Events\\AbstractEvent;\n    \n    class CountEvent extends AbstractEvent implements EventInterface, EventPublisherInterface\n    {\n        /**\n         * Changel name. For client side this is nsp.\n         */\n        public static function broadcastOn(): array\n        {\n            return ['notifications'];\n        }\n    \n        /**\n         * Event name\n         */\n        public static function name(): string\n        {\n            return 'update_notification_count';\n        }\n            \n        /**\n         * Emit client event\n         * @return array\n         */\n        public function fire(): array\n        {\n            return [\n                'count' =\u003e 10,\n            ];\n        }\n    }\n```\n```js\n    var socket = io('{your_host_address}:1367/notifications');\n    socket.on('update_notification_count', function(data){\n        console.log(data)\n    });\n```\n\n###### Create receiver from client to server\n```php\n    use SfCod\\SocketIoBundle\\Events\\EventInterface;\n    use SfCod\\SocketIoBundle\\Events\\EventSubscriberInterface;\n    use SfCod\\SocketIoBundle\\Events\\AbstractEvent;\n    use SfCod\\SocketIoBundle\\Service\\Broadcast;\n\n    class MarkAsReadEvent extends AbstractEvent implements EventInterface, EventSubscriberInterface\n    {\n\n        private $broadcast;\n    \n        public function __construct(Broadcast $broadcast)\n        {\n            $this-\u003ebroadcast = $broadcast;\n        }\n\n        /**\n         * Changel name. For client side this is nsp.\n         */\n        public static function broadcastOn(): array\n        {\n            return ['notifications'];\n        }\n    \n        /**\n         * Event name\n         */\n        public static function name(): string\n        {\n            return 'mark_as_read_notification';\n        }\n            \n        /**\n         * Handle client event\n         */\n        public function handle()\n        {\n            // Mark notification as read\n            // And call client update\n            $this-\u003ebroadcast-\u003eemit('update_notification_count', ['some key' =\u003e 'some value']);\n        }\n    }\n```\n\n```js\n    var socket = io('{your_host_address}:1367/notifications');\n    socket.emit('mark_as_read_notification', {id: 10});\n```\n\nYou can have publisher and receiver in one event. If you need check data from client to server you should use: \n- EventPolicyInterface\n\n###### Receiver with checking from client to server\n```php\n    use SfCod\\SocketIoBundle\\Events\\EventSubscriberInterface;\n    use SfCod\\SocketIoBundle\\Events\\EventInterface;\n    use SfCod\\SocketIoBundle\\Events\\EventPolicyInterface;\n    use SfCod\\SocketIoBundle\\Events\\AbstractEvent;\n    use SfCod\\SocketIoBundle\\Service\\Broadcast;\n\n    class MarkAsReadEvent extends AbstractEvent implements EventInterface, EventSubscriberInterface, EventPolicyInterface\n    {\n\n        private $broadcast;\n    \n        public function __construct(Broadcast $broadcast)\n        {\n            $this-\u003ebroadcast = $broadcast;\n        }\n\n        /**\n         * Changel name. For client side this is nsp.\n         */\n        public static function broadcastOn(): array\n        {\n            return ['notifications'];\n        }\n    \n        /**\n         * Event name\n         */\n        public static function name(): string\n        {\n            return 'mark_as_read_notification';\n        }\n         \n        public function can($data): bool\n        {\n            // Check data from client    \n            return true;\n        }        \n        \n        /**\n         * Emit client event\n         * @return array\n         */\n        public function handle()\n        {\n            // Mark notification as read\n            // And call client update\n            $this-\u003ebroadcast-\u003eemit('update_notification_count', ['some key' =\u003e 'some value']);\n        }\n    }\n```\n\nSocket.io rooms\n---------------\n\n- EventRoomInterface (Backend side)\n```php\n    use SfCod\\SocketIoBundle\\Events\\EventPublisherInterface;\n    use SfCod\\SocketIoBundle\\Events\\EventInterface;\n    use SfCod\\SocketIoBundle\\Events\\EventRoomInterface;\n    use SfCod\\SocketIoBundle\\Events\\AbstractEvent;\n\n    class CountEvent extends AbstractEvent implements EventInterface, EventPublisherInterface, EventRoomInterface\n    {           \n        /**\n         * Changel name. For client side this is nsp.\n         */\n        public static function broadcastOn(): array\n        {\n            return ['notifications'];\n        }\n    \n        /**\n         * Event name\n         */\n        public static function name(): string\n        {\n            return 'update_notification_count';\n        }\n           \n        /**\n         * Socket.io room\n         * @return string\n         */\n        public function room(): string\n        {\n            return 'user_id_' . $this-\u003euserId;\n        }            \n            \n        /**\n         * Emit client event\n         * @return array\n         */\n        public function fire(): array\n        {                        \n            return [\n                'count' =\u003e 10,\n            ];\n        }\n    }\n```\nClient side\n```js\n    var socket = io('{your_host_address}:1367/notifications');\n    socket.emit('join', {room: 'user_id_10'});\n    // Now you will receive data from 'room-1'\n    socket.on('update_notification_count', function(data){\n        console.log(data)\n    });\n    // You can leave room\n    socket.emit('leave', {room: 'user_id_10'});\n```\nRun this on the backend side\n```php\n$this-\u003ebroadcast-\u003eemit('update_notification_count', ['some key' =\u003e 'some value', 'userId' =\u003e 10]);\n```\n\n###### Default events:\n- connection\n- disconnect\n- join\n- leave\n```php\n    use SfCod\\SocketIoBundle\\Events\\EventSubscriberInterface;\n    use SfCod\\SocketIoBundle\\Events\\EventInterface;\n    use Psr\\Log\\LoggerInterface;\n    use SfCod\\SocketIoBundle\\Events\\AbstractEvent;\n    \n    class СonnectionEvent extends AbstractEvent implements EventInterface, EventSubscriberInterface\n    {\n\n        private $logger;\n    \n        public function __construct(LoggerInterface $logger)\n        {\n            $this-\u003elogger = $logger;\n        }\n\n        /**\n         * Changel name. For client side this is nsp.\n         */\n        public static function broadcastOn(): array\n        {\n            return ['notifications'];\n        }\n    \n        /**\n         * Event name\n         */\n        public static function name(): string\n        {\n            return 'connection'; // or 'disconnect'\n        }     \n        \n        /**\n         * Handle client event\n         */\n        public function handle()\n        {\n            // Socket.io ID\n            // $this-\u003esocketId\n            $this-\u003elogger-\u003einfo('disconnect', $this-\u003epayload);\n        }\n    }\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsfcod%2Fsocketio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsfcod%2Fsocketio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsfcod%2Fsocketio/lists"}