安装
bash
composer require workerman/workerman
创建命令
text
php think make:command 命令文件名 命令名
实例一:秒级定时任务
文件位置
text
app/command/TimerTest.php
代码
php
<?php
namespace app\command;
use think\console\Command;
use Workerman\Worker;
use Workerman\Timer;
use app\common\model\Order;
class TimerTest extends Command
{
protected function configure()
{
$this->setName('timer');
}
protected function execute(Input $input, Output $output)
{
$worker = new Worker();
$worker->onWorkerStart = function() {
// 每秒任务
Timer::add(1, function() {
$count = Order::where('status', 0)
->where('create_time', '<', time() - 1800)
->update(['status' => -1]);
if ($count) echo "自动关闭 {$count} 个超时订单\n";
});
// 每5秒任务
Timer::add(5, function() {
echo "5秒任务执行: " . date('Y-m-d H:i:s') . "\n";
});
// 每60秒任务
Timer::add(60, function() {
cache('visit_count', 0);
echo "已重置访问计数\n";
});
};
Worker::runAll();
}
}
配置 config/console.php
php
<?php
return [
'commands' => [
'timer' => 'app\command\TimerTest',
],
];
启动
bash
# Linux 后台运行
php think timer start -d
# Windows 开发
php think timer start
实例二:WebSocket 实时通信
文件位置
shell
app/command/WebSocket.php
代码
php
<?php
namespace app\command;
use think\console\Command;
use Workerman\Worker;
class WebSocket extends Command
{
protected function configure()
{
$this->setName('websocket');
}
protected function execute(Input $input, Output $output)
{
$ws = new Worker('websocket://0.0.0.0:8282');
$ws->count = 4;
$ws->onMessage = function($connection, $data) {
// 广播消息
foreach(Worker::$connections as $conn) {
$conn->send($data);
}
};
Worker::runAll();
}
}
配置 config/console.php
php
<?php
return [
'commands' => [
'websocket' => 'app\command\WebSocket',
],
];
启动
bash
php think websocket start -d
实例三:TP8 接口中触发 WebSocket 推送(内部 Text 端口)
设计思路
WebSocket 服务运行在独立进程中,TP8 HTTP 接口无法直接调用。解决方案:在同一进程内再监听一个内部端口(8281),接口通过 TCP 短连接发送消息。
text
TP8 接口 → TCP 8281 (Text协议: 消息+换行符) → WebSocket 8282 → 客户端
文件位置
text
app/command/PushServer.php
代码
php
<?php
namespace app\command;
use think\console\Command;
use Workerman\Worker;
class PushServer extends Command
{
protected function configure()
{
$this->setName('push-server');
}
protected function execute(Input $input, Output $output)
{
// WebSocket 服务(对外,8282端口)
$ws = new Worker('websocket://0.0.0.0:8282');
$ws->count = 4;
$ws->onMessage = function($connection, $data) {
foreach(Worker::$connections as $conn) {
$conn->send($data);
}
};
// 内部推送服务(对内,8281端口,Text协议)
$internal = new Worker('text://0.0.0.0:8281');
$internal->onMessage = function($connection, $data) {
// 收到内部推送消息,广播给所有 WebSocket 客户端
foreach(Worker::$connections as $conn) {
$conn->send($data);
}
// 回应客户端
$connection->send("OK\n");
};
Worker::runAll();
}
}
配置 config/console.php
php
<?php
return [
'commands' => [
'push-server' => 'app\command\PushServer',
],
];
TP8 接口中推送
php
<?php
namespace app\api\controller;
use think\Controller;
use app\common\model\Message;
class Api extends Controller
{
public function send()
{
$content = $this->request->post('content');
// 连接到内部推送端口
$socket = stream_socket_client('tcp://127.0.0.1:8281',$errno, $errmsg, 3);
if ($socket) {
// 发送消息(换行符结尾表示一条完整消息)
fwrite($socket, $content . "\n");
// 读取回应(可选)
$response = fgets($socket);
fclose($socket);
return json(['code' => 0, 'msg' => '发送成功']);
}
return json(['code' => 1, 'msg' => '推送失败: ' . $errstr]);
}
}
启动
bash
php think push-server start -d
命令速查
bash
# 开发
php think timer start
# 生产
php think timer start -d
# 停止
php think timer stop
# 重启
php think timer restart
# 平滑重启(不断连)
php think timer reload