在 ServBay 中搭建和运行 Workerman 应用
概述
本篇文档旨在指导 ServBay 用户如何在本地 macOS 和 Windows 开发环境中,利用 ServBay 集成的 PHP 环境和 Composer,快速搭建并运行基于 Workerman 的高性能异步网络应用。Workerman 是一个强大的 PHP 库,适用于构建各种需要高并发处理的网络服务,如 Web 服务器、实时通信服务器、游戏服务器等。ServBay 提供了一个开箱即用的开发平台,极大地简化了 Workerman 的环境配置过程。
什么是 Workerman?
Workerman 是一个完全由 PHP 编写的开源高性能异步网络通信框架。它基于 EventLoop 事件循环机制,实现了异步非阻塞 I/O,能够有效处理大量并发连接。与传统的 PHP Web 开发模式(如 Apache/Nginx + PHP-FPM)不同,Workerman 应用通常以常驻内存的方式运行,监听特定端口,直接处理网络连接和数据,从而避免了传统模式下请求处理完成后进程销毁带来的开销,显著提升了性能和吞吐量。
利用 Workerman,开发者可以轻松构建:
- 高性能的 HTTP 服务器,甚至可以替代 Apache/Nginx 处理简单的静态或动态请求。
- 实时 WebSocket 服务器,用于构建聊天室、实时数据推送等应用。
- 各种自定义协议的 TCP/UDP 服务器。
- 命令行工具、计划任务、微服务等。
Workerman 的核心特性与优势
- 高性能: 核心基于事件驱动和异步非阻塞 I/O,能够处理海量并发连接,提供卓越的性能表现。
- 多协议支持: 内置支持 HTTP、WebSocket、TCP、UDP 等多种主流网络协议,并提供了灵活的接口允许开发者实现自定义协议。
- 易于使用: 提供简洁直观的 API,降低了异步网络编程的复杂性,PHP 开发者可以快速上手。
- 灵活扩展: 支持多进程模型,便于利用多核 CPU 进行水平扩展和负载均衡。可以方便地集成 Composer 包和现有的 PHP 库。
- PHP 生态融合: 作为 PHP 库,与 PHP 现有生态系统紧密结合,可以无缝使用 Composer 管理依赖。
- 守护进程模式: 支持以守护进程(Daemon)方式在后台稳定运行,适合生产环境部署,保证服务的持续可用性。
Workerman 为 PHP 开发者打开了构建高性能、实时、高并发网络应用的大门。
使用 ServBay 搭建 Workerman 开发环境
ServBay 是一款专为 Web 开发者量身打造的本地开发环境工具,集成了 PHP、Node.js、Python、Go、Java 等多种主流编程语言运行时,以及 Caddy、Nginx、Apache、MySQL、PostgreSQL、MongoDB、Redis、Memcached 等常用数据库和服务器软件。ServBay 的核心优势在于其“开箱即用”的特性,特别是它内置并配置好了 Composer 环境,这为在 ServBay 中搭建和运行 Workerman 项目提供了极大的便利。
本指南将通过创建几个基础示例,演示如何在 ServBay 环境中快速搭建并运行 Workerman 应用,包括一个简单的 HTTP 服务器、一个 WebSocket 服务器和一个 TCP 服务器。
TIP
为了方便管理和统一规范,ServBay 建议将所有本地网站项目文件存放在以下目录下:
- macOS:
/Applications/ServBay/www
- Windows:
C:\ServBay\www
本文档中的所有项目路径示例均将基于此目录。
前提条件
在开始之前,请确保满足以下条件:
- ServBay 已安装并正常运行: 访问 ServBay 官方网站 下载并安装最新版本的 ServBay。
- ServBay 中的 PHP 已启用: 在 ServBay 控制面板中,确保你计划使用的 PHP 版本已启用。Workerman 需要 PHP 5.4 或更高版本,推荐使用 PHP 7.x 或 8.x 版本以获得最佳性能。
- 具备基础的 PHP 编程和命令行操作知识: 你需要了解基本的 PHP 语法和如何在终端中使用命令行工具。
安装 Workerman
1. 确保 Composer 可用
ServBay 已经内置了 Composer,无需单独安装。请确保你的 ServBay 环境已启动,并且你计划使用的 PHP 版本已启用。ServBay 会自动配置好对应 PHP 版本的 Composer 环境。你可以通过 ServBay 的终端或者外部终端(如果 ServBay 已将 PHP 和 Composer 添加到系统 PATH)进入 ServBay 的 PHP 环境来使用 Composer。
打开终端,输入以下命令验证 Composer 是否可用:
bash
composer -v
1
如果 Composer 正确安装并配置在 ServBay 的 PHP 环境中,你将看到 Composer 的版本信息。如果命令未找到,请检查 ServBay 是否正在运行以及 PHP 版本是否已启用。
2. 创建项目目录
导航到 ServBay 推荐的网站根目录,并创建一个新的项目目录,然后进入该目录:
macOS:
bash
cd /Applications/ServBay/www
mkdir servbay-workerman-demo
cd servbay-workerman-demo
1
2
3
2
3
Windows:
cmd
cd C:\ServBay\www
mkdir servbay-workerman-demo
cd servbay-workerman-demo
1
2
3
2
3
这里我们创建了一个名为 servbay-workerman-demo
的目录来存放 Workerman 项目文件。
3. 使用 Composer 安装 Workerman
在项目目录中,使用 Composer 安装 Workerman 库。这是推荐的安装方式,Composer 会自动处理依赖:
项目目录路径:
- macOS:
/Applications/ServBay/www/servbay-workerman-demo
- Windows:
C:\ServBay\www\servbay-workerman-demo
bash
composer require workerman/workerman
1
Composer 将会自动下载 Workerman 及其依赖到当前目录下的 vendor
目录中。
编写 Workerman HTTP 服务器代码
HTTP 服务器是 Workerman 最常见的应用场景之一,可以用于构建高性能的 Web 应用或 API 服务。
在项目目录下创建一个名为 http_server.php
(或者你喜欢的其他名称,例如 server.php
)的文件,并添加以下 PHP 代码:
php
<?php
// 引入 Composer 的自动加载文件,以便使用 Workerman 类
require __DIR__ . '/vendor/autoload.php';
// 导入 Workerman 的 Worker 类
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
use Workerman\Protocols\Http\Response;
// 创建一个 Worker 实例,指定监听的协议和地址
// 'http://0.0.0.0:8080' 表示创建一个 HTTP 服务器,监听所有网络接口(0.0.0.0)的 8080 端口
// 0.0.0.0 允许从本机或局域网内的其他设备访问;8080 是监听的端口号。
$http_worker = new Worker('http://0.0.0.0:8080');
// 设置 Worker 进程的数量
// 这里设置为 4,表示启动 4 个独立的 PHP 进程来处理请求,可以根据 CPU 核心数进行调整
$http_worker->count = 4;
// 定义当接收到客户端消息(HTTP 请求)时的处理逻辑
// $connection 是当前的连接对象,通过它可以向客户端发送响应
// $request 是当前的请求对象,包含了请求的详细信息(URL, Headers, Body 等)
$http_worker->onMessage = function(TcpConnection $connection, Request $request) {
// 向客户端发送一个简单的字符串作为 HTTP 响应
// Workerman 的 HTTP 协议会自动处理 HTTP 响应头等细节
$connection->send(new Response(200, [], 'Hello ServBay Workerman HTTP Server!'));
};
// 运行所有的 Worker 实例
// 这是 Workerman 的主循环,启动后 Worker 进程开始监听端口并处理事件
Worker::runAll();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
代码解释:
require __DIR__ . '/vendor/autoload.php';
: 载入 Composer 生成的自动加载文件,使得 Workerman 的类(包括Worker
,Request
,Response
等)可以被使用。use Workerman\...;
: 引入需要的类。new Worker('http://0.0.0.0:8080')
: 创建一个 Workerman 实例。参数指定了监听的协议(http
)和地址(0.0.0.0:8080
)。$http_worker->count = 4;
: 设置 Workerman 启动的进程数量。增加进程数可以利用多核 CPU,提高并发处理能力。$http_worker->onMessage = function(TcpConnection $connection, Request $request) { ... };
: 定义了当 Workerman 接收到完整的 HTTP 请求时执行的回调函数。$connection
对象用于发送数据回客户端,$request
对象包含客户端发送的请求信息。Response
类用于构建标准的 HTTP 响应。Worker::runAll();
: 启动 Workerman 的事件循环,使所有定义的 Worker 实例开始监听并处理连接。
运行 Workerman HTTP 服务器
在项目目录中,打开终端,运行以下命令启动 HTTP 服务器:
项目目录路径:
- macOS:
/Applications/ServBay/www/servbay-workerman-demo
- Windows:
C:\ServBay\www\servbay-workerman-demo
bash
php http_server.php start
1
运行模式说明:
- 前台模式 (Foreground): 执行
php http_server.php start
命令后,Workerman 会在前台运行,终端会输出运行信息和日志。你可以通过Ctrl+C
停止服务器。这种模式适合开发和调试。 - 守护进程模式 (Daemon): 在生产环境中,通常需要让 Workerman 在后台作为守护进程稳定运行。可以使用
-d
参数:bashWorkerman 将在后台运行,并将输出重定向到日志文件(默认在 Workerman 目录下或指定路径)。php http_server.php start -d
1
进程管理:
Workerman 提供了一系列方便的进程管理命令:
- 启动:
php http_server.php start
(前台) 或php http_server.php start -d
(后台) - 停止:
php http_server.php stop
(会等待当前请求处理完毕后优雅退出) - 重启:
php http_server.php restart
(先停止再启动) - 平滑重启 (Reload):
php http_server.php reload
(通常用于代码更新,会逐个重启子进程,不中断服务,但需要注意onWorkerStart
等生命周期函数的使用) - 查看状态:
php http_server.php status
(查看 Workerman 进程的运行状态、内存占用、连接数等信息)
启动服务器后,打开浏览器,访问 http://localhost:8080
或 http://127.0.0.1:8080
。您应该会看到页面输出 Hello ServBay Workerman HTTP Server!
。
使用 Workerman 创建 WebSocket 服务器
WebSocket 协议允许客户端和服务器之间建立持久的双向通信连接,非常适合构建实时应用,如在线聊天、股票行情、游戏等。Workerman 对 WebSocket 有良好的支持。
创建 WebSocket 服务器代码
在项目目录下创建一个
websocket_server.php
文件,并添加以下代码:php<?php require __DIR__ . '/vendor/autoload.php'; use Workerman\Worker; use Workerman\Connection\TcpConnection; // 创建一个 WebSocket 服务器实例,监听 8081 端口 // 'websocket://0.0.0.0:8081' 表示创建一个 WebSocket 服务器 // Workerman 会自动处理 WebSocket 的握手过程 $ws_worker = new Worker('websocket://0.0.0.0:8081'); // 启动 4 个进程来处理连接 $ws_worker->count = 4; // 定义连接建立时的处理逻辑 // 当有新的客户端连接到服务器时触发 $ws_worker->onConnect = function(TcpConnection $connection) { echo "New WebSocket connection from " . $connection->getRemoteIp() . "\n"; }; // 定义消息接收时的处理逻辑 // 当服务器收到客户端发送的 WebSocket 消息时触发 // $data 是从客户端接收到的消息内容(已解码) $ws_worker->onMessage = function(TcpConnection $connection, $data) { echo "Received message: " . $data . "\n"; // 向客户端回显收到的消息 // $connection->send() 会自动编码为 WebSocket 帧发送 $connection->send('ServBay Workerman received: ' . $data); }; // 定义连接关闭时的处理逻辑 // 当客户端断开连接时触发 $ws_worker->onClose = function(TcpConnection $connection) { echo "WebSocket Connection closed\n"; }; // 定义发生错误时的处理逻辑 (可选) $ws_worker->onError = function(TcpConnection $connection, $code, $msg) { echo "Error: $code - $msg\n"; }; // 运行所有的 Worker 实例 Worker::runAll();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44运行 WebSocket 服务器
在项目目录下运行以下命令启动 WebSocket 服务器:
bashphp websocket_server.php start
1您同样可以使用
-d
参数在后台运行。启动后,您可以使用 WebSocket 客户端工具连接到ws://localhost:8081
。例如,您可以在浏览器开发者工具的 Console 中使用 JavaScript 进行测试:
javascriptvar ws = new WebSocket("ws://localhost:8081"); ws.onopen = function(event) { console.log("WebSocket connection opened"); ws.send("Hello from Browser!"); // 发送消息 }; ws.onmessage = function(event) { console.log("Message from server:", event.data); // 接收消息 }; ws.onclose = function(event) { if (event.wasClean) { console.log("WebSocket connection closed cleanly, code=" + event.code + " reason=" + event.reason); } else { console.error("WebSocket connection died"); } }; ws.onerror = function(error) { console.error("WebSocket error:", error); }; // 关闭连接 (可选) // ws.close();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25连接成功后,您将看到终端输出连接信息,发送消息后,终端会显示收到的消息,并且浏览器会收到服务器回显的消息。
使用 Workerman 创建 TCP 服务器
Workerman 也可以用于创建通用的 TCP 服务器,处理各种基于 TCP 协议的应用层数据。这对于构建游戏后端、物联网平台、自定义通信服务等非常有用。
创建 TCP 服务器代码
在项目目录下创建一个
tcp_server.php
文件,并添加以下代码:php<?php require __DIR__ . '/vendor/autoload.php'; use Workerman\Worker; use Workerman\Connection\TcpConnection; // 创建一个 TCP 服务器实例,监听 8082 端口 // 'tcp://0.0.0.0:8082' 表示创建一个 TCP 服务器 // Workerman 默认使用 Text 协议(行结束符 '\n'),也可以指定其他协议或自定义协议 $tcp_worker = new Worker('tcp://0.0.0.0:8082'); // 启动 4 个进程来处理连接 $tcp_worker->count = 4; // 定义连接建立时的处理逻辑 $tcp_worker->onConnect = function(TcpConnection $connection) { echo "New TCP connection from " . $connection->getRemoteIp() . "\n"; // 连接建立时发送欢迎消息 $connection->send("Welcome to ServBay Workerman TCP Server!\n"); }; // 定义消息接收时的处理逻辑 // $data 是从客户端接收到的原始 TCP 数据(根据协议解析后的数据) $tcp_worker->onMessage = function(TcpConnection $connection, $data) { echo "Received data: " . $data; // 向客户端回显收到的数据 $connection->send('ServBay Workerman received: ' . $data); }; // 定义连接关闭时的处理逻辑 $tcp_worker->onClose = function(TcpConnection $connection) { echo "TCP Connection closed\n"; }; // 运行所有的 Worker 实例 Worker::runAll();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36运行 TCP 服务器
在项目目录下运行以下命令启动 TCP 服务器:
bashphp tcp_server.php start
1您同样可以使用
-d
参数在后台运行。启动后,您可以使用 TCP 客户端工具连接到localhost:8082
。例如,打开另一个终端窗口,输入
telnet
或nc
命令:bash# 使用 telnet telnet localhost 8082 # 或者使用 nc (netcat) nc localhost 8082
1
2
3
4
5连接成功后,您将看到服务器发送的欢迎消息。输入任意文本(以回车结束,因为默认使用了 Text 协议),服务器将会回显您发送的消息。
注意事项
- 端口占用: 确保 Workerman 监听的端口(示例中的 8080, 8081, 8082)没有被 macOS 系统或 ServBay 中运行的其他程序占用。如果端口冲突,Workerman 将无法启动并报错。你可以通过
lsof -i :端口号
命令来检查端口占用情况。 - 防火墙: 操作系统的内置防火墙可能会阻止外部设备访问这些端口。在本地开发环境中,通常不是问题,但如果需要从局域网内的其他设备访问 Workerman 服务,请检查并配置操作系统的防火墙设置。
- 与 ServBay Web 服务器的关系: Workerman 运行在自己监听的端口上,与 ServBay 中运行的 Caddy 或 Nginx 是独立的进程和服务。Workerman 应用通常直接处理连接,而不是通过 Caddy/Nginx 代理(除非你专门配置反向代理)。Workerman 更适合处理需要长时间连接或高并发异步处理的场景(如 WebSocket),而 ServBay 集成的 Caddy/Nginx 主要用于处理传统的、短连接的 HTTP 请求。
- PHP 版本: 确保 ServBay 中用于运行 Workerman 的 PHP 版本符合 Workerman 的最低要求。ServBay 支持并预装了多个 PHP 版本,你可以根据项目需求在 ServBay 控制面板中选择并启用合适的版本。
- 扩展依赖: Workerman 依赖于一些 PHP 扩展以获得最佳性能和功能,例如
event
扩展(如果安装且启用,Workerman 会优先使用,提供更高的性能)、posix
、pcntl
(用于多进程模式)。ServBay 默认启用了大部分常用扩展,但如果遇到特定问题,请检查 ServBay 控制面板中对应 PHP 版本的扩展是否已启用。 - 日志: 在守护进程模式下,Workerman 的输出会重定向到日志文件。请定期检查日志文件以了解应用运行状态和潜在错误。
常见问题解答 (FAQ)
- Q: 如何停止 Workerman 服务器?
- A: 如果服务器在前台运行(使用
start
命令),直接在终端中按Ctrl+C
即可停止。如果服务器在后台作为守护进程运行(使用start -d
命令),则需要在项目目录下使用命令php your_server_file.php stop
来停止。
- A: 如果服务器在前台运行(使用
- Q: 为什么 Workerman 服务器无法启动?
- A: 最常见的原因是监听的端口已被占用。请检查终端输出的错误信息,通常会提示端口被占用。你可以尝试更换一个未被占用的端口,或者停止占用该端口的其他程序。使用
lsof -i :端口号
命令可以查看哪个进程占用了特定端口。
- A: 最常见的原因是监听的端口已被占用。请检查终端输出的错误信息,通常会提示端口被占用。你可以尝试更换一个未被占用的端口,或者停止占用该端口的其他程序。使用
- Q: ServBay 的 Caddy/Nginx 和 Workerman 有什么区别?我应该用哪个?
- A: ServBay 的 Caddy/Nginx 是传统的 Web 服务器,主要用于处理标准的 HTTP/HTTPS 请求,通常与 PHP-FPM 配合工作,每个请求处理完毕后 PHP 进程可能会退出。Workerman 是一个 PHP 异步网络框架,可以自己作为 HTTP 服务器,也可以处理 WebSocket、TCP 等其他协议,它以常驻内存的方式运行,更适合处理高并发、长连接或实时通信的应用。选择哪个取决于你的应用需求:传统网站或 RESTful API 通常使用 Caddy/Nginx;实时聊天、游戏后端、物联网服务等更适合使用 Workerman。当然,你也可以结合使用,例如用 Caddy/Nginx 作为反向代理转发特定请求到 Workerman。
- Q: 我可以在 ServBay 中同时运行多个 Workerman 应用吗?
- A: 可以。每个 Workerman 应用都需要在一个独立的 PHP 进程中运行,并且监听不同的端口。只需为每个应用编写单独的启动脚本,并在不同的终端窗口中运行
php your_app_server.php start
命令(或在后台运行)即可。确保它们监听的端口不冲突。
- A: 可以。每个 Workerman 应用都需要在一个独立的 PHP 进程中运行,并且监听不同的端口。只需为每个应用编写单独的启动脚本,并在不同的终端窗口中运行
总结
通过本指南,你已经了解了如何在 ServBay 这一高效的本地开发环境中,快速搭建和运行 Workerman 项目。Workerman 凭借其高性能和异步特性,为 PHP 开发者提供了构建下一代网络应用的强大能力。结合 ServBay 提供的开箱即用的 Composer 和 PHP 环境,你可以极大地提高开发效率,专注于 Workerman 应用的业务逻辑实现,而无需花费大量时间在环境配置上。无论是构建高性能的 Web 服务,还是开发实时交互的 WebSocket 应用,ServBay 都是你使用 Workerman 的理想本地开发伙伴。希望本文能帮助你顺利开启 Workerman 的探索之旅!