PHP code example of topthink / think-swoole

1. Go to this page and download the library: Download topthink/think-swoole library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

topthink / think-swoole example snippets


use Swoole\Coroutine as Co;
use think\swoole\Coroutine;

Coroutine::create(function () use ($task) {
    Co::sleep(1.5); //sleep 由 Swoole\Coroutine 提供
    $task(); //继承请求的沙箱,请求协程会等待其执行完成
});

use Swoole\Timer;
use think\swoole\Manager;

//在请求(或其他沙箱)中注册定时器
$manager = app(Manager::class);

Timer::after(1000, function () use ($manager, $task) {
    //回调协程没有归属,套一层独立沙箱后即可正常使用容器
    $manager->runInSandbox(function () use ($task) {
        $task();
    });
});

return [
    'redis' => [
        'default'     => 'default',
        'connections' => [
            'default' => [
                'host'                => '127.0.0.1',
                'port'                => 6379,
                'password'            => '',
                'database'            => 0,
                'timeout'             => 10,
                'max_active'          => 10,
                'max_wait_time'       => 5,
                'max_idle_time'       => 20,
                'idle_check_interval' => 10,
            ],
        ],
    ],
];

return [
    'ipc' => [
        'redis' => [
            'connection' => 'default',
            'prefix'     => 'swoole:ipc:',
        ],
    ],
    'websocket' => [
        'room' => [
            'redis' => [
                'connection' => 'default',
                'prefix'     => 'swoole:room:',
            ],
        ],
    ],
    'task' => [
        'redis' => [
            'connection' => 'default',
            'prefix'     => 'swoole:task:',
        ],
    ],
];

return [
    'redis' => [
        'connection' => 'default',
    ],
];

use think\swoole\facade\Redis;

$value = Redis::connection()->run(function (\Redis $client) {
    return $client->get('key');
});

Redis::connection()->set('key', 'value');

// SUBSCRIBE、MONITOR 等阻塞或独占命令
Redis::connection()->dedicated(function (\Redis $client) {
    // ...
});

return [
    'lock' => [
        'enable' => true,
        'type'   => 'redis',
        'redis'  => [
            'connection' => 'default',
            'prefix'     => 'swoole:lock:',
        ],
    ],
];

use think\swoole\Lock;

$lock = app(Lock::class);
$lock->lock('order:' . $orderId, 30);

try {
    // 临界区必须短于 30 秒
} finally {
    $lock->unlock('order:' . $orderId);
}

use think\swoole\facade\Task;

$taskId = Task::create(function () use ($task) {
    $task();
});

if (!Task::isRunning($taskId)) {
    // 最近一个租约周期内没有心跳,任务已结束或执行进程已失联
}

Task::create($callback, 'order:' . $orderId);

Task::run('order:' . $orderId, function () use ($orderId) {
    // 在当前协程中同步执行
});

return [
    'task' => [
        'heartbeat_interval' => 5,
        'lease_ttl'          => 15,
        'redis'              => [
            'connection' => 'default',
            'prefix'     => 'swoole:task:',
        ],
    ],
];

Route::get('static/:path', function (string $path) {
    $filename = public_path() . $path;
    return new \think\swoole\response\File($filename);
})->pattern(['path' => '.*\.\w+$']);

return [
    // ...
    'queue'      => [
        'enable'  => true,
        //键名是队列名称
        'workers' => [
            //下面参数是不设置时的默认配置
            'default'            => [
                'delay'      => 0,
                'sleep'      => 3,
                'tries'      => 0,
                'timeout'    => 60,
                'worker_num' => 1,
            ],
            //使用@符号后面可指定队列使用驱动
            'default@connection' => [
                //此处可不设置任何参数,使用上面的默认配置
            ],
        ],
    ],
    // ...
];


Route::get('path1','controller/action1');
Route::get('path2','controller/action2');

use \think\swoole\Websocket;
use \think\swoole\websocket\Event;
use \Swoole\WebSocket\Frame;
use \think\swoole\websocket\Room;

class Controller {

    public function action1(){//不可以在这里注入websocket对象
    
        return \think\swoole\helper\websocket()
            ->onOpen(...)
            ->onMessage(function(Websocket $websocket, Frame $frame){ //只可在事件响应这里注入websocket对象
                //...
                $websocket->join('room_key'); //将当前连接加入到某个room,后续可以向该room发送消息 这个room里的都可以收到
                //比如room_key可以直接使用这个用户的id,然后其他地方需要给某个用户发送消息,直接向这个room发送消息即可
                //...
                $websocket->push('message'); //给当前连接发送消息
                //...
                $websocket->emit('event_name', 'message'); //给当前连接发送事件
                //...
                $websocket->to('room_key')->push('message'); //给指定room的所有连接发送消息 在http请求的控制器中也可以注入Websocket对象这样发消息
                //...
            })
            ->onClose(...);
    }
    
    public function action2(){
    
        return \think\swoole\helper\websocket()
            ->onOpen(...)
            ->onMessage(function(Websocket $websocket, Frame $frame){
               //...
            })
            ->onClose(...);
    }
}

use think\swoole\facade\Pusher;

// 向单个房间推送消息
Pusher::to('room_key')->push('message');

// 同时向多个房间推送
Pusher::to('room_a', 'room_b')->push('message');
Pusher::to(['room_a', 'room_b'])->push('message');

// 向房间推送事件
Pusher::to('user_1001')->emit('notice', ['content' => 'message']);


class Controller {

    public function action(){
        return \think\swoole\helper\iterator(value(function(){
            foreach(range(1,10) as $i)
                yield $i;
                sleep(1);//模拟等待
            }
        }));
    }
}

public function download()
{
    $stream = fopen(runtime_path() . 'large-file.zip', 'rb');

    return \think\swoole\helper\stream($stream)
        ->header([
            'Content-Type'        => 'application/zip',
            'Content-Disposition' => 'attachment; filename="large-file.zip"',
        ]);
}

\think\swoole\helper\stream($stream, 8192, false);