# 配置文件

##### 1. 运行环境

应用的运行环境最常用的是开发、测试、生产三种环境，因此beyod也内置了支持，以便于实现基于运行环境的配置特性。
APP_ENV环境变量指明了运行环境，可在系统环境变量中配置为dev, test, prod, 分别代表开发、测试、生产环境。
如果没有配置，则默认为dev环境。
每种运行环境中，部分配置参数肯定不同，因此我们引入运行环境相关配置和全局配置。

另请参阅 配置运行环境变量

##### 2. 配置文件

config/main.php 全局配置文件
config/(dev|test|prod)/main.php 运行环境相关的配置
配置文件加载时，将环境相关的配置项与全局配置项合并后运行。
绝大多数配置项使用yii风格的组件化配置，由组件名称，组件类，类的属性组成。
每个组件的配置项，就对应了组件类的公共属性或setter方法。

config/main.php

    <?php

    use yii\helpers\Markdown;

    $config = [
        'id' => 'beyod',
        'basePath' => dirname(__DIR__).'/app', //指定应用根目录为app
        'bootstrap' => ['log'], //yii框架需要
        'language' => 'zh-CN',  //中文
        'timeZone' => 'PRC', //中国时区
        'enableCoreCommands' => false, //不加载yii的其它命令

        //php beyod.php server/start 实际上就是调用了以下控制器。
        'controllerMap' => [
            'server' => [
                'class' => 'beyod\ServerController',
             ]
        ],

        //组件配置
        'components' => [
            //server组件表示当前服务实例，名称必须为server
            'server' => [
                'class' => 'app\MyServer', //表示使用app\MyServer自定义类实现服务实例，必须从beyoio\Server继承
                'server_id' => 1, //server实例id, 集群环境中，每个节点此值必须唯一。
                'pid_file' => '@runtime/beyod.pid', //指定pid文件路径 @runtime指向 app/runtime
                'worker_num' => 4, //工作进程数量，生产环境建议设置为CPU的2~4倍， windows下无效。
                'daemonize' => false, //是否以后台守护进程运行，windows下无效，当设置为false时，程序将在终端挂起不转入后台要运行，以便于调试
                'user' => 'nobody', //工作进程启动后的切换用户账号，可限制工作进程的越权系统访问，对保证系统安全性有极其重要作用。
                'group' => 'nobody', //同上，设置用户组
                'rlimit_nofile' => 65535, //设置单个进程打开的连接数和文件数，仅PHP 7+以上有效，其它版本中，需要手工调整Linux系统的rlimie_nofile参数至少为60000以上，以便能接受大量并发连接。
                'memory_limit' => '1024MB', //每个工作进程允许使用的内存上限，一旦超限将导致当前工作进程退出并重启(1GB)。

                //指定此服务实例每个进程中要监听的端口以及对应的parser/handler, 键名必须是listenners
                'listeners' => [
                    //定义一个listenner，名称为text(名称可以自定义)
                    'text' => [
                        'class' => 'beyod\Listener',//指定侦听器的类，你可以使用自定义的类
                        'listen' => 'tcp://0.0.0.0:7723', //监听tcp端口7723
                        'parser' => 'beyoio\dispatcher\Parser', //指定协议解析器
                        'handler' => 'beyoio\dispatcher\Handler' //指定网络事件处理器
                    ],

                    //同上，我们启动了一个集群分发器
                    'dispatch' => [
                        'class' => 'beyod\Listener',
                        'listen' => 'tcp://0.0.0.0:7724',
                        'parser' => 'beyoio\dispatcher\Parser',
                        'handler' => 'beyoio\dispatcher\Handler'
                    ],

                    //这是一个http server配置
                    'http' => [
                        'class' => 'beyod\Listener',
                        'listen' => 'tcp://0.0.0.0:7725',
                        'parser' => 'beyod\protocol\http\Parser',
                        'handler' => [
                            //指定此handler的类以及属性配置，熟悉Yii框架的对此不会陌生。
                            'class'=>'beyod\protocol\http\Handler',
                            'gzip'=>true,
                            'document_root' => dirname(__DIR__).'/webroot',
                            'callback' =>[
                                '#\.md$#' => function($event, $req, $res, $path){
                                    $res->body = Markdown::process(file_get_contents($path), 'gfm-comment');
                                    return true;
                                },
                            ]
                        ]
                    ],

                    //这是一个websocket服务器，监听在7726端口
                    'websocket' => [
                        'listen' => 'tcp://0.0.0.0:7726',
                        'handler' => [
                            'class' => 'app\ChatHandler',//使用我们自己的处理器
                        ],

                        //指定协议解析器
                        'parser' => [
                            'class' => 'beyod\protocol\websocket\Parser',
                        ]
                    ],
                ],
            ],

            //libevent的封装
            'eventLooper' => [
                'class' => 'beyod\event\Event',
            ],

            'errorHandler' => [
                'class'=>'beyod\helpers\ErrorHandler',
            ],

            'db' => [
                'class' => 'yii\db\Connection',
                'dsn' => 'mysql:host=localhost;dbname=utf8;charset=utf8',
                'username' => '',
                'password' => '',
                'charset' => 'utf8',
            ],

            'cache' => [
                'class' => 'yii\caching\FileCache',
            ],

            //指定日志文件目标和参数
            'log' => [
                'traceLevel' => 0,
                'FlushInterval' => 1,
                'targets' => [
                    'default' => [
                        'class' => 'beyod\helpers\FileTarget',
                        'logFile' => '@runtime/logs/beyod.warning.log',
                        'levels' => ['error', 'warning', 'info'],
                    ],

                    'debug' => [
                        'class' => 'beyod\helpers\FileTarget',
                        'logFile' => '@runtime/logs/beyod.debug.log',
                        'levels' => ['error', 'warning', 'info', 'trace'],
                    ],

                    //直接在控制台输出日志内容，调试时非常有用, 生产环境中应关闭。
                    'console' => [
                        'class' => 'beyod\helpers\ConsoleTarget',
                        'logVars' => [],
                        'enabled' => APP_ENV === 'dev' || DIRECTORY_SEPARATOR === "\\",
                        'exportInterval' =>1,
                        'levels' => ['error', 'warning', 'info','trace'],
                    ],
                ],
            ],

        ],
        'params' => [

        ],
    ];

    return \yii\helpers\ArrayHelper::merge(
        $config,
        require __DIR__.'/'.YII_ENV.'/'.basename(__FILE__)
    );