本文目录导读:

Swoole通过内置的WebSocket\Server类来实现WebSocket服务,底层基于异步非阻塞的事件驱动模型,以下是实现步骤和核心机制:
基础服务器搭建
<?php
use Swoole\WebSocket\Server;
use Swoole\Http\Request;
use Swoole\WebSocket\Frame;
// 创建WebSocket服务器,监听0.0.0.0:9501
$server = new Server('0.0.0.0', 9501);
// 设置运行参数
$server->set([
'worker_num' => 4, // 工作进程数
'max_request' => 10000, // 每个进程最大处理请求数
'task_worker_num' => 4, // 异步任务进程数(可选)
]);
// 注册事件回调
// 1. HTTP握手事件
$server->on('request', function (Request $request, $response) {
// 处理HTTP请求(如果有)
$response->end("<h1>WebSocket Server</h1>");
});
// 2. WebSocket连接建立事件
$server->on('open', function (Server $server, $request) {
echo "客户端 #{$request->fd} 已连接\n";
// 可发送欢迎消息
$server->push($request->fd, "欢迎连接服务器,您的ID: {$request->fd}");
});
// 3. 消息接收事件
$server->on('message', function (Server $server, Frame $frame) {
echo "收到来自 #{$frame->fd} 的消息: {$frame->data}\n";
// 处理消息
$response = processMessage($frame->data);
// 回复客户端
$server->push($frame->fd, $response);
// 广播给所有客户端
broadcast($server, $frame->fd, $frame->data);
});
// 4. 连接关闭事件
$server->on('close', function (Server $server, $fd) {
echo "客户端 #{$fd} 已断开\n";
});
// 5. 错误处理
$server->on('error', function (Server $server, $fd, $errorCode) {
echo "客户端 #{$fd} 错误: {$errorCode}\n";
});
// 启动服务器
$server->start();
/**
* 消息处理函数
*/
function processMessage($data) {
// 这里可以添加业务逻辑
return "已收到消息: " . $data;
}
/**
* 广播消息给所有客户端
*/
function broadcast(Server $server, $excludeFd = null, $data) {
foreach ($server->connections as $fd) {
// 排除发送者
if ($fd !== $excludeFd) {
$server->push($fd, "广播: {$data}");
}
}
}
核心事件机制
Swoole WebSocket的完整事件流:
| 事件 | 说明 | 触发时机 |
|---|---|---|
start |
服务器启动 | 主进程启动时 |
open |
握手成功 | WebSocket连接建立后 |
message |
接收消息 | 收到客户端消息 |
close |
连接关闭 | 客户端断开或服务器主动关闭 |
request |
HTTP请求 | 当HTTP服务器功能启用时 |
handshake |
自定义握手 | 如果需要自定义握手逻辑 |
task/finish |
异步任务 | 任务投递和完成时 |
配置选项详解
$server->set([
// 基础配置
'worker_num' => 4, // 工作进程数,建议CPU核心数*2
'max_request' => 10000, // 进程最大处理请求数后重启
'max_conn' => 1000, // 最大连接数
// TCP配置
'backlog' => 128, // 监听队列长度
'open_tcp_nodelay' => true, // 禁用Nagle算法
// WebSocket配置
'websocket_subprotocol' => '', // 子协议
'open_websocket_close_frame' => true, // 开启关闭帧处理
'websocket_compression' => true, // 启用压缩
// 性能优化
'dispatch_mode' => 2, // 数据分发策略
'reload_async' => true, // 异步重启
'enable_static_handler' => false, // HTTP静态文件处理
]);
高级功能实现
1 自定义握手(验证Token)
$server->on('handshake', function (Request $request, $response) {
// 验证头信息
$token = $request->header['sec-websocket-protocol'] ?? '';
if (!validateToken($token)) {
$response->status(403);
$response->end('Forbidden');
return false; // 拒绝连接
}
// 继续握手流程
return true;
});
2 异步任务处理
$server->on('message', function (Server $server, Frame $frame) {
// 投递到任务进程处理
$taskData = [
'fd' => $frame->fd,
'data' => $frame->data,
'time' => time()
];
$server->task($taskData);
});
$server->on('task', function (Server $server, $taskId, $fromId, $data) {
// 处理耗时任务
$result = processHeavyTask($data);
// 返回结果到工作进程
return $result;
});
$server->on('finish', function (Server $server, $taskId, $data) {
// 任务完成,可以发送给客户端
echo "任务 #{$taskId} 完成: {$data}\n";
});
客户端连接示例
<!DOCTYPE html>
<html>
<body>
<script>
const ws = new WebSocket('ws://localhost:9501');
ws.onopen = function() {
console.log('连接成功');
ws.send('Hello Server!');
};
ws.onmessage = function(event) {
console.log('收到消息:', event.data);
};
ws.onclose = function() {
console.log('连接已关闭');
};
ws.onerror = function(error) {
console.error('错误:', error);
};
</script>
</body>
</html>
监控与管理
// 获取所有连接 $connections = $server->connections; // 获取客户端信息 $clientInfo = $server->getClientInfo($fd); // 获取当前服务器状态 $stats = $server->stats(); // 主动关闭连接 $server->close($fd, true); // true表示优雅关闭
Swoole的WebSocket服务具有高性能、低延迟的特点,适合实时聊天、游戏、数据推送等场景,它的事件驱动模型使得开发者可以轻松处理大量并发连接,同时支持异步任务处理,非常适合构建实时应用服务。