arkotik / yii2-socketio
为 Yii2 框架提供的简单而强大的 socketio
1.2.5.1
2019-09-19 14:12 UTC
Requires
- ext-json: *
- predis/predis: ~1.1.0
- symfony/process: ~3.0|~4.0
- yiicod/yii2-base: 1.*
- yiicod/yii2-cron: 1.*
- yiisoft/yii2: 2.*
Requires (Dev)
README
在您的 Yii 2 项目中充分利用 socket.io 的所有功能。
配置
安装 node + 额外的 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
控制台配置(简单分支)
'controllerMap' => [ 'socketio' => [ 'class' => \yiicod\socketio\commands\SocketIoCommand::class, 'server' => 'localhost:1367' ], ]
启动 sockeio 服务器
php yii socketio/start
停止 sockeio 服务器
php yii socketio/stop
控制台配置 + PM2(https://pm2.node.org.cn/)。这种变体更适合控制台配置
'controllerMap' => [ 'socketio' => [ 'class' => \yiicod\socketio\commands\WorkerCommand::class, 'server' => 'localhost:1367' ], ]
pm2 配置
{ "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" }, ] }
运行 PM2 守护进程
pm2 start daemons-app.json
PM2 将在后台运行这两个命令:
php yii socketio/node-js-server php yii socketio/php-server
通用配置
'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, ], ]
从服务器创建发布者到客户端
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])
从客户端创建接收者到服务器
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});
您可以在一个事件中拥有发布者和接收者。如果您需要从客户端检查数据到服务器,您应该使用
- EventPolicyInterface
具有从客户端到服务器检查功能的接收者
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 有房间功能。如果您需要它,您应该实现
- 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])