本文目录导读:

我来详细讲解如何在PHP项目中集成和使用Workerman。
安装Workerman
使用Composer安装(推荐)
# 在项目根目录执行 composer require workerman/workerman
手动安装
# 下载源码 git clone https://github.com/walkor/Workerman.git
基础示例代码
简单HTTP服务器
<?php
// server.php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
// 创建一个Worker监听端口,使用http协议
$http_worker = new Worker('http://0.0.0.0:8080');
// 设置进程数
$http_worker->count = 4;
// 接收到浏览器发送的数据时会触发此事件
$http_worker->onMessage = function(TcpConnection $connection, Request $request) {
// 设置响应头
$connection->send("Hello World");
};
// 运行worker
Worker::runAll();
启动服务器:
php server.php start
WebSocket服务器示例
<?php
// websocket.php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
// 创建WebSocket服务器
$ws_worker = new Worker('websocket://0.0.0.0:8080');
// 设置进程数
$ws_worker->count = 1;
// 建立连接时触发
$ws_worker->onConnect = function(TcpConnection $connection) {
echo "新连接: {$connection->getRemoteIp()}\n";
$connection->send('欢迎连接WebSocket服务器!');
};
// 接收到消息时触发
$ws_worker->onMessage = function(TcpConnection $connection, $data) {
echo "收到消息: {$data}\n";
// 发送消息给客户端
$connection->send("服务端回复: {$data}");
};
// 连接关闭时触发
$ws_worker->onClose = function(TcpConnection $connection) {
echo "连接关闭\n";
};
Worker::runAll();
与框架集成
在Laravel中使用
<?php
// app/Console/Commands/WorkermanCommand.php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Workerman\Worker;
class WorkermanCommand extends Command
{
protected $signature = 'workerman:start {action?}';
protected $description = 'Workerman服务器管理';
public function handle()
{
$action = $this->argument('action') ?: 'start';
$worker = new Worker('http://0.0.0.0:8080');
$worker->count = 4;
$worker->onMessage = function($connection, $request) {
$connection->send('Laravel + Workerman');
};
Worker::runAll();
}
}
在ThinkPHP中使用
<?php
// application/command/Workerman.php
namespace app\command;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use Workerman\Worker;
class Workerman extends Command
{
protected function configure()
{
$this->setName('workerman:start')
->setDescription('Start Workerman');
}
protected function execute(Input $input, Output $output)
{
$worker = new Worker('http://0.0.0.0:8080');
$worker->count = 4;
$worker->onMessage = function($connection, $request) {
$connection->send('ThinkPHP + Workerman');
};
Worker::runAll();
}
}
进阶用法
定时任务
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
use Workerman\Lib\Timer;
$task_worker = new Worker();
$task_worker->count = 1;
$task_worker->onWorkerStart = function($worker) {
// 每5秒执行一次
$time_interval = 5;
$timer_id = Timer::add($time_interval, function() {
echo "定时任务执行\n";
});
};
Worker::runAll();
心跳检测
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
use Workerman\Lib\Timer;
$ws_worker = new Worker('websocket://0.0.0.0:8080');
$ws_worker->count = 1;
$ws_worker->onConnect = function($connection) {
$connection->lastPingTime = time();
// 设置定时器检查心跳
$connection->timer_id = Timer::add(10, function() use ($connection) {
if (time() - $connection->lastPingTime > 30) {
echo "心跳超时,关闭连接\n";
$connection->close();
}
});
};
$ws_worker->onMessage = function($connection, $data) {
if ($data === 'ping') {
$connection->lastPingTime = time();
$connection->send('pong');
} else {
$connection->send("收到: {$data}");
}
};
Worker::runAll();
部署配置
生产环境启动脚本
#!/bin/bash
# start.sh
case "$1" in
start)
echo "Starting Workerman..."
php server.php start -d
;;
stop)
echo "Stopping Workerman..."
php server.php stop
;;
restart)
echo "Restarting Workerman..."
php server.php restart
;;
status)
echo "Checking Workerman status..."
php server.php status
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac
Nginx代理配置
# nginx.conf
upstream workerman {
server 127.0.0.1:8080;
# 如果有多个Worker实例
# server 127.0.0.1:8081;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://workerman;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 86400;
}
}
安全考虑
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
// 限制访问IP
$worker = new Worker('http://0.0.0.0:8080');
$worker->onMessage = function($connection, $request) {
$allowed_ips = ['127.0.0.1', '192.168.1.*'];
$client_ip = $connection->getRemoteIp();
if (!in_array($client_ip, $allowed_ips)) {
$connection->close();
return;
}
$connection->send('安全连接');
};
// 设置运行用户
$worker->user = 'www-data';
$worker->group = 'www-data';
Worker::runAll();
性能优化
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
$worker = new Worker('http://0.0.0.0:8080');
// 设置进程数(根据CPU核心数设置)
$worker->count = 4;
// 开启reusePort(Linux 3.9+)
$worker->reusePort = true;
// 设置连接超时
$worker->connections = 1024;
// 使用更少的IO操作
$worker->onMessage = function($connection, $request) {
// 使用Redis/Memcached缓存
static $cache = [];
$cache_key = $request->path();
if (isset($cache[$cache_key])) {
$connection->send($cache[$cache_key]);
return;
}
// 业务逻辑
$result = "Response for: {$cache_key}";
$cache[$cache_key] = $result;
$connection->send($result);
};
// 设置事件循环
$worker->eventLoop = \Workerman\Events\Ev::class;
Worker::runAll();
常见问题解决
端口被占用
# 检查端口
netstat -anp | grep 8080
# 使用不同端口
$worker = new Worker('http://0.0.0.0:9090');
内存不足
// 限制内存使用
ini_set('memory_limit', '256M');
// 设置单进程处理连接数限制
$worker->maxRequestCount = 1000;
日志管理
// 设置日志文件 Worker::$logFile = '/var/log/workerman.log'; Worker::$stdoutFile = '/var/log/workerman_stdout.log';
Workerman真正强大的地方在于它的事件驱动架构,特别适合高并发、长连接或实时通信场景,如果你想深入某个功能(比如WebSocket聊天室、长连接优化等),可以具体问我。