Swoole如何实现WebSocket服务?

wen PHP项目 47

本文目录导读:

Swoole如何实现WebSocket服务?

  1. 基础服务器搭建
  2. 核心事件机制
  3. 配置选项详解
  4. 高级功能实现
  5. 客户端连接示例
  6. 监控与管理

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服务具有高性能、低延迟的特点,适合实时聊天、游戏、数据推送等场景,它的事件驱动模型使得开发者可以轻松处理大量并发连接,同时支持异步任务处理,非常适合构建实时应用服务。

抱歉,评论功能暂时关闭!