Skip to content
No description or website provided.
Branch: master
Clone or download
Latest commit bf3a2c9 Jun 15, 2018
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
commands Changed serializer Jun 15, 2018
drivers Init May 25, 2017
events Init May 25, 2017
server Nodejs server improvement Apr 1, 2018
.gitignore Small improvement Feb 18, 2018
.php_cs Refactor main class Jul 21, 2017
.scrutinizer.yml Small improvement Feb 18, 2018
Broadcast.php Fix class call Feb 19, 2018
EventManager.php Init May 25, 2017
Process.php Changed serializer Jun 15, 2018
README.md Readme small improvement Apr 27, 2018
SocketIoAsset.php Add comments Aug 25, 2017
composer.json Small improvement Feb 18, 2018

README.md

Socket.io Yii extension

Use all power of socket.io in your Yii 2 project.

Latest Stable Version Total Downloads Scrutinizer Code QualityCode Climate

Config

Install node + additional npm
    cd ~
    curl -sL https://deb.nodesource.com/setup_6.x -o nodesource_setup.sh
    sudo bash nodesource_setup.sh
    cd vendor/yiicod/yii2-soketio/server
    npm install

Console config (simple fork)

    'controllerMap' => [
        'socketio' => [
            'class' => \yiicod\socketio\commands\SocketIoCommand::class,
            'server' => 'localhost:1367'
        ],
    ]       
Start sockeio server
    php yii socketio/start
Stop sockeio server
    php yii socketio/stop

Console config + PM2(http://pm2.keymetrics.io/). This variant more preferable for console configuration

    'controllerMap' => [
        'socketio' => [
            'class' => \yiicod\socketio\commands\WorkerCommand::class,
            'server' => 'localhost:1367'
        ],
    ]
pm2 config:
    {
      "apps": [
        {
          "name": "socket-io-node-js-server",
          "script": "yii",
          "args": [
            "socketio/node-js-server"
          ],
          "exec_interpreter": "php",
          "exec_mode": "fork_mode",
          "max_memory_restart": "1G",
          "watch": false,
          "merge_logs": true,
          "out_file": "runtime/logs/node_js_server_out.log",
          "error_file": "runtime/logs/node_js_server_err.log"
        },
        {
          "name": "socket-io-php-server",
          "script": "yii",
          "args": [
            "socketio/php-server"
          ],
          "exec_interpreter": "php",
          "exec_mode": "fork_mode",
          "max_memory_restart": "1G",
          "watch": false,
          "merge_logs": true,
          "out_file": "runtime/logs/php_server_out.log",
          "error_file": "runtime/logs/php_server_err.log"
        },
      ]
    }
Run PM2 daemons
pm2 start daemons-app.json
PM2 will be run these two commands in background::
    php yii socketio/node-js-server
    php yii socketio/php-server
Common config
    'components' =>[
        'broadcastEvents' => [
            'class' => \yiicod\socketio\EventManager::class,
            'nsp' => 'some_unique_key',
            // Namespaces with events folders
            'namespaces' => [
                'app\socketio',
            ]
        ],
        'broadcastDriver' => [
            'class' => \yiicod\socketio\drivers\RedisDriver::class,
            'hostname' => 'localhost',
            'port' => 6379,
        ],    
    ]
Create publisher from server to client
    use yiicod\socketio\events\EventInterface;
    use yiicod\socketio\events\EventPubInterface;
    
    class CountEvent implements EventInterface, EventPubInterface
    {
        /**
         * Changel name. For client side this is nsp.
         */
        public static function broadcastOn(): array
        {
            return ['notifications'];
        }
    
        /**
         * Event name
         */
        public static function name(): string
        {
            return 'update_notification_count';
        }
            
        /**
         * Emit client event
         * @param array $data
         * @return array
         */
        public function fire(array $data): array
        {
            return $data;
        }
    }
    var socket = io('localhost:1367/notifications');
    socket.on('update_notification_count', function(data){
        console.log(data)
    });
    //Run broadcast to client
    \yiicod\socketio\Broadcast::emit(CountEvent::name(), ['count' => 10])
Create receiver from client to server
    use yiicod\socketio\events\EventInterface;
    use yiicod\socketio\events\EventSubInterface;
    
    class MarkAsReadEvent implements EventInterface, EventSubInterface
    {
        /**
         * Changel name. For client side this is nsp.
         */
        public static function broadcastOn(): array
        {
            return ['notifications'];
        }
    
        /**
         * Event name
         */
        public static function name(): string
        {
            return 'mark_as_read_notification';
        }
            
        /**
         * Emit client event
         * @param array $data
         * @return array
         */
        public function handle(array $data)
        {
            // Mark notification as read
            // And call client update
            // Broadcast::emit('update_notification_count', ['some_key' => 'some_value']);
            
            // Push some log
            file_put_contents(\Yii::getAlias('@app/../file.txt'), serialize($data));
        }
    }
    var socket = io('localhost:1367/notifications');
    socket.emit('mark_as_read_notification', {id: 10});

You can have publisher and receiver in one event. If you need check data from client to server you should use:

  • EventPolicyInterface
Receiver with checking from client to server
    use yiicod\socketio\events\EventSubInterface;
    use yiicod\socketio\events\EventInterface;
    use yiicod\socketio\events\EventPolicyInterface;
    
    class MarkAsReadEvent implements EventInterface, EventSubInterface, EventPolicyInterface
    {
        /**
         * Changel name. For client side this is nsp.
         */
        public static function broadcastOn(): array
        {
            return ['notifications'];
        }
    
        /**
         * Event name
         */
        public static function name(): string
        {
            return 'mark_as_read_notification';
        }
         
        public function can($data): bool
        {
            // Check data from client    
            return true;
        }        
        
        /**
         * Emit client event
         * @param array $data
         * @return array
         */
        public function handle(array $data)
        {
            // Mark notification as read
            // And call client update
            Broadcast::emit('update_notification_count', ['some_key' => 'some_value']);
        }
    }

Soket.io has room functionl. If you need it, you should implement:

  • EventRoomInterface
    use yiicod\socketio\events\EventPubInterface;
    use yiicod\socketio\events\EventInterface;
    use yiicod\socketio\events\EventRoomInterface;
    
    class CountEvent implements EventInterface, EventPubInterface, EventRoomInterface
    {
        /**
         * User id
         * @var int
         */
        protected $userId;
        
        /**
         * Changel name. For client side this is nsp.
         */
        public static function broadcastOn(): array
        {
            return ['notifications'];
        }
    
        /**
         * Event name
         */
        public static function name(): string
        {
            return 'update_notification_count';
        }
           
        /**
         * Socket.io room
         * @return string
         */
        public function room(): string
        {
            return 'user_id_' . $this->>userId;
        }            
            
        /**
         * Emit client event
         * @param array $data
         * @return array
         */
        public function fire(array $data): array
        {
            $this->userId = $data['userId'];
            return [
                'count' => 10,
            ];
        }
    }
    var socket = io('localhost:1367/notifications');
    socket.emit('join', {room: 'user_id_'<?= 10 ?>});
    // Now you will receive data from 'room-1'
    socket.on('update_notification_count', function(data){
        console.log(data)
    });
    // You can leave room
    socket.emit('leave');
    //Run broadcast to user id = 10 
    \yiicod\socketio\Broadcast::emit(CountEvent::name(), ['count' => 10, 'userId' => 10])
You can’t perform that action at this time.