CRMEB聊天模塊的學習(一)

首先看CRMEB駐留內存的bat

start cmd /c php think workerman start chat
start cmd /c php think workerman start admin
start cmd /c php think timer start
php think workerman start channel

程序啓動於think文件

#!/usr/bin/env php
<?php
namespace think;

// 加載基礎文件
require __DIR__ . '/vendor/autoload.php';

// 應用初始化
(new App())->console->run();

CRMEB基於ThinkPHP,ThinkPHP按composer的模式整理了程序的啓動過程,有空的小白應該可能去認真研讀一下autoload.php內部的相關代碼,這樣對學習進程會很有幫助

通過命名空間think找到vendor/topthink/framework/src/think/Console.php文件,Console類中,__construct函數通過loadCommands函數加載了配置

    /**
     * 加載指令
     * @access protected
     */
    protected function loadCommands(): void
    {
        $commands = $this->app->config->get('console.commands', []);
        $commands = array_merge($this->defaultCommands, $commands);

        $this->addCommands($commands);
    }

注意到$this->app->config->get從console.commands讀配置,那配置文件在哪裏呢?這就需要回過頭來研讀一下App.php這個文件了(文章所限,省略掉不重要的代碼)

    public function initialize()
    {
        ......
        // 加載全局初始化文件
        $this->load();
        ......
	}

    protected function load(): void
    {
        ......
        foreach ($files as $file) {
            $this->config->load($file, pathinfo($file, PATHINFO_FILENAME));
        }
		.....
    }

通過代碼得知,程序加載時,即從/config目錄下,把所有配置文件都加載進來,console.commands配置項即是console.php配置文件中的commands配置項。那我們就可以知道,聊天相關的對象是在\crmeb\command\Workerman這個類中。

下面來看一下Workerman類的execute方法,workerServer屬性與chatWorkerServer長連接對象都是Worker對象實例,這個大家要學一下Workerman的資料了:

protected function execute(Input $input, Output $output)
    {
        $server = $this->init($input, $output);
        Worker::$pidFile = app()->getRootPath().'workerman.pid';
        if(!$server || $server == 'admin'){
            var_dump('admin');
            //創建 admin 長連接服務
            $this->workerServer = new Worker($this->config['admin']['protocol'] . '://' . $this->config['admin']['ip'] . ':' . $this->config['admin']['port']);
            $this->workerServer->count = $this->config['admin']['serverCount'];
        }

        if(!$server || $server == 'chat') {
            var_dump('chat');
            //創建 h5 chat 長連接服務
            $this->chatWorkerServer = new Worker($this->config['chat']['protocol'] . '://' . $this->config['chat']['ip'] . ':' . $this->config['chat']['port']);
            $this->chatWorkerServer->count = $this->config['chat']['serverCount'];
        }

        if(!$server || $server == 'channel') {
            var_dump('channel');
            //創建內部通訊服務
            $this->channelServer = new Server($this->config['channel']['ip'], $this->config['channel']['port']);
        }
        $this->bindHandle();
        try {
            Worker::runAll();
        } catch (\Exception $e) {
            $output->warning($e->getMessage());
        }
    }

注意:配置是從$this->config[‘admin’][‘protocol’],查找配置文件的目錄workerman.php配置文件包含了這些配置項,配置項是通過config函數來讀的,config函數是在/vendor/topthink/framework/src/helper.php文件中,也是用Config類讀取配置的

從bindHandle方法中,得知ChatService是接收聊天對話的業務類

    protected function bindHandle()
    {
        if(!is_null($this->workerServer)){
            $server = new WorkermanService($this->workerServer, $this->channelServer);
            // 連接時回調
            $this->workerServer->onConnect = [$server, 'onConnect'];
            // 收到客戶端信息時回調
            $this->workerServer->onMessage = [$server, 'onMessage'];
            // 進程啓動後的回調
            $this->workerServer->onWorkerStart = [$server, 'onWorkerStart'];
            // 斷開時觸發的回調
            $this->workerServer->onClose = [$server, 'onClose'];
        }

        if(!is_null($this->chatWorkerServer)) {
            $chatServer = new ChatService($this->chatWorkerServer, $this->channelServer);
            $this->chatWorkerServer->onConnect = [$chatServer, 'onConnect'];
            $this->chatWorkerServer->onMessage = [$chatServer, 'onMessage'];
            $this->chatWorkerServer->onWorkerStart = [$chatServer, 'onWorkerStart'];
            $this->chatWorkerServer->onClose = [$chatServer, 'onClose'];
        }
    }

/crmeb/service/workerman/chat/ChatService.php文件中,ChatService類用ChatHandle來進行業務相關操作,對於需要進行二次開發的小白來說,可以修改ChatHandle來完善業務功能,我感覺也可以通過傳入的參數調用不同業務對象的功能,這樣才能實現靈活擴展的目的。

好了,就聊到這

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章