laravel+laravels+架构直播聊天

环境

软件 版本
laravel 6.18.3
laravel-s 3.7.0
supervisord /进程守护
redis /消息发布订阅

流程图

laravel+laravels+架构直播聊天_第1张图片

1.消息发布

\Illuminate\Support\Facades\Redis::connection('default')->command('PUBLISH',[
'key',
'data'
]);

2.消息订阅监听

php代码



namespace App\Console\Commands;

use App\Repository\AliYun\Consumer;
use App\Repository\Redis\ChatPubSubRedisRepository;
use Illuminate\Console\Command;

class Chat extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'chat:subscribe';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $sub = new ChatPubSubRedisRepository();
        $sub->sub();
    }
}

supervisord进程守护

# redis发布订阅
[program:xxx-xxx-xxx-xxx-chat-subscribe]
process_name=%(program_name)s_%(process_num)02d
command=php 项目目录/artisan chat:subscribe
autostart=true
autorestart=true
user=root
numprocs=1
redirect_stderr=true

3.消息订阅存入本地队列

try
{
    Redis::connection('default')->subscribe('key',function ($mes){
        log_websocketinfo('接收订阅消息:'.$mes);
        // 存储本地redis的消息队列
        $chatList = new ChatListRedisRepository();
        $chatList->lpush($mes);
    });
}catch (\Exception $exception)
{
}

4.队列通过定时任务消费

配置文件配置定时任务

'jobs'          => [
   // Enable LaravelScheduleJob to run `php artisan schedule:run` every 1 minute, replace Linux Crontab
   //\Hhxsv5\LaravelS\Illuminate\LaravelScheduleJob::class,
   // Two ways to configure parameters:
   // [\App\Jobs\XxxCronJob::class, [1000, true]], // Pass in parameters when registering
   // \App\Jobs\XxxCronJob::class, // Override the corresponding method to return the configuration
   \App\Jobs\MiCronJob::class,
],

定时任务代码


/**
 * Created by PhpStorm.
 * User: EricPan
 * Date: 2020/5/8
 * Time: 9:52
 */

namespace App\Jobs;

use App\Tasks\TestTask;
use Swoole\Coroutine;
use Hhxsv5\LaravelS\Swoole\Task\Task;
use Hhxsv5\LaravelS\Swoole\Timer\CronJob;

class MiCronJob extends CronJob
{
    protected $i = 0;
    // !!! 定时任务的`interval`和`isImmediate`有两种配置方式(二选一):一是重载对应的方法,二是注册定时任务时传入参数。
    // --- 重载对应的方法来返回配置:开始
    public function interval()
    {
        return 1;// 每100毫秒运行一次
    }
    public function isImmediate()
    {
        return false;// 是否立即执行第一次,false则等待间隔时间后执行第一次
    }
    // --- 重载对应的方法来返回配置:结束
    public function run()
    {
//        \Log::info(__METHOD__, ['start', $this->i, microtime(true)]);
        // do something
        // sleep(1); // Swoole < 2.1
        Coroutine::sleep(1); // Swoole>=2.1 run()方法已自动创建了协程。
        // 定时任务消费消息队列代码
        Task::deliver(new TestTask());
//        $this->i++;
//        \Log::info(__METHOD__, ['end', $this->i, microtime(true)]);

//        if ($this->i >= 10) { // 运行10次后不再执行
//            \Log::info(__METHOD__, ['stop', $this->i, microtime(true)]);
//            $this->stop(); // 终止此任务
            // CronJob中也可以投递Task,但不支持Task的finish()回调。
            // 注意:修改config/laravels.php,配置task_ipc_mode为1或2,参考 https://wiki.swoole.com/#/server/setting?id=task_ipc_mode
//            $ret = Task::deliver(new TestTask('task data'));
//            var_dump($ret);
//        }
        // throw new \Exception('an exception');// 此时抛出的异常上层会忽略,并记录到Swoole日志,需要开发者try/catch捕获处理
    }
}

你可能感兴趣的:(laravel)