技术 2026年06月16日 👤 mdo 👁 0 阅读

Swoole http server 如何处理http消息推送

在Swoole HTTP服务器中实现HTTP消息推送需要结合WebSocket服务。以下是实现方案:

  1. 配置说明
    当前配置中WebSocket服务已启用,监听在9514端口。HTTP消息推送可以通过以下方式实现:

    a. 通过HTTP接口触发WebSocket消息推送
    b. 使用Swoole的task机制异步处理推送逻辑

  2. 实现HTTP消息推送的步骤

    a. 创建HTTP接口控制器
    需要创建一个控制器来接收HTTP请求并触发消息推送:

<?php
namespace app\controller;

use think\facade\Request;
use think\swoole\Websocket;

class PushController
{
    public function push(Websocket $websocket)
    {
        // 获取推送参数
        $data = Request::param();
        $to = $data['to'] ?? 'all'; // 接收者:all(所有人)、room(房间)、user(指定用户)
        $message = $data['message'] ?? '';
        $event = $data['event'] ?? 'message';
        
        if (empty($message)) {
            return json(['code' => 400, 'msg' => '消息内容不能为空']);
        }
        
        try {
            switch ($to) {
                case 'room':
                    // 推送到指定房间
                    $roomId = $data['room_id'] ?? '';
                    if (empty($roomId)) {
                        throw new \Exception('房间ID不能为空');
                    }
                    $websocket->to($roomId)->emit($event, $message);
                    break;
                    
                case 'user':
                    // 推送给指定用户
                    $userId = $data['user_id'] ?? '';
                    if (empty($userId)) {
                        throw new \Exception('用户ID不能为空');
                    }
                    $websocket->to($userId)->emit($event, $message);
                    break;
                    
                default:
                    // 广播给所有人
                    $websocket->emit($event, $message);
            }
            
            return json(['code' => 0, 'msg' => '推送成功']);
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => $e->getMessage()]);
        }
    }
}

b. 配置路由
在路由配置文件中添加推送接口的路由:

// HTTP消息推送路由
Route::post('push', 'app/controller/PushController/push');

c. 使用task机制优化性能
对于大量推送或耗时操作,可以使用Swoole的task机制异步处理:

<?php
namespace app\controller;

use think\facade\Request;
use think\swoole\Manager;

class PushController
{
    public function push(Manager $manager)
    {
        $data = Request::param();
        
        // 将推送任务投递到task进程异步处理
        $manager->task('push', function ($task) use ($data) {
            // 在task进程中执行推送逻辑
            $websocket = app('think\swoole\Websocket');
            
            $to = $data['to'] ?? 'all';
            $message = $data['message'] ?? '';
            $event = $data['event'] ?? 'message';
            
            if (empty($message)) {
                return ['code' => 400, 'msg' => '消息内容不能为空'];
            }
            
            try {
                switch ($to) {
                    case 'room':
                        $roomId = $data['room_id'] ?? '';
                        if (empty($roomId)) {
                            throw new \Exception('房间ID不能为空');
                        }
                        $websocket->to($roomId)->emit($event, $message);
                        break;
                        
                    case 'user':
                        $userId = $data['user_id'] ?? '';
                        if (empty($userId)) {
                            throw new \Exception('用户ID不能为空');
                        }
                        $websocket->to($userId)->emit($event, $message);
                        break;
                        
                    default:
                        $websocket->emit($event, $message);
                }
                
                return ['code' => 0, 'msg' => '推送成功'];
            } catch (\Exception $e) {
                return ['code' => 500, 'msg' => $e->getMessage()];
            }
        });
        
        return json(['code' => 0, 'msg' => '推送任务已提交']);
    }
}
  1. 使用示例

    a. 广播消息给所有连接:

// POST请求
http://your-domain.com/push
// 请求体
{
    "message": "这是一条广播消息",
    "event": "broadcast"
}

b. 推送消息到指定房间:

 

// POST请求
http://your-domain.com/push
// 请求体
{
    "to": "room",
    "room_id": "room_123",
    "message": "房间消息",
    "event": "room_message"
}

c. 推送消息给指定用户:

// POST请求
http://your-domain.com/push
// 请求体
{
    "to": "user",
    "user_id": "user_456",
    "message": "用户消息",
    "event": "user_message"
}
  1. 注意事项

    a. 确保WebSocket服务已正确配置并运行
    b. 客户端需要先建立WebSocket连接才能接收推送消息
    c. 对于大量推送,建议使用task机制异步处理
    d. 可以在WsOpen事件监听器中实现用户认证和房间管理逻辑
    e. 推送消息的大小受package_max_length配置限制,当前为20MB

这种实现方式允许通过HTTP接口触发WebSocket消息推送,实现了HTTP到WebSocket的消息转发,可以满足各种实时消息推送场景的需求。