avatar

mdo

Hello

  • 首页
  • 知识库
  • 归档
  • 标签
  • 关于
主页 Swoole http server 如何处理http消息推送
文章

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

发表于 2026-06-16 更新于 2026-06- 16
作者 mdo
11~14 分钟 阅读

在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的消息转发,可以满足各种实时消息推送场景的需求。

技术
许可协议:  CC BY 4.0
分享

相关文章

7月 26, 2026

完美地解决 TP3 老系统数据的平滑读取

为了彻底、完美地解决 TP3 老系统数据的平滑读取,必须解决两个核心痛点: TP3 的盲猜反序列化机制(标量存原样,数组/对象存原生 serialize,同时兼容 json)。 TP3 与 TP6 的缓存前缀(Prefix)不一致。 以下是为你量身定制的终极落地解决方案,通

7月 26, 2026

thinkphp3 redis序列化和反序列化

在老系统重构迁移至 ThinkPHP 6 (TP6) 的过程中,ThinkPHP 3 (TP3) 的 Redis 序列化历史遗留问题是最核心的连环坑之一。 TP3 的 S('key', $value) 缓存方法和底层 Redis 驱动,在存储非字符串(如数组、对象)时,有一套独特的序列化行为。如果不

7月 24, 2026

Table 空间极易发生哈希冲突并溢出

既然你没有在业务中主动调用 Room,只使用了全局广播,那么这个问题就非常明确了:即使你不用房间功能,think-swoole 只要开启了 WebSocket,底层就会强行初始化并注入一个名为 Room 的驱动组件。 [1] 框架底层默认使用 table 类型来作为 Room 的存储介质。当进行全局

下一篇

think-swoole-websocket

上一篇

http协议推送websocket

最近更新

  • 完美地解决 TP3 老系统数据的平滑读取
  • thinkphp3 redis序列化和反序列化
  • Table 空间极易发生哈希冲突并溢出
  • 将监控程序直接跑在云端
  • AI 驱动型 Facebook 群组关键词监控 Chrome 浏览器插件

热门标签

API CodeGeex Gitkraken Management Manticore Premiere Sublime Swoole ThinkPHP ThinkPHP5

目录

©2026 mdo. 保留部分权利。