Swoole http server 如何处理http消息推送
在Swoole HTTP服务器中实现HTTP消息推送需要结合WebSocket服务。以下是实现方案:
配置说明
当前配置中WebSocket服务已启用,监听在9514端口。HTTP消息推送可以通过以下方式实现:a. 通过HTTP接口触发WebSocket消息推送
b. 使用Swoole的task机制异步处理推送逻辑实现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' => '推送任务已提交']);
}
}
使用示例
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"
}
注意事项
a. 确保WebSocket服务已正确配置并运行
b. 客户端需要先建立WebSocket连接才能接收推送消息
c. 对于大量推送,建议使用task机制异步处理
d. 可以在WsOpen事件监听器中实现用户认证和房间管理逻辑
e. 推送消息的大小受package_max_length配置限制,当前为20MB
这种实现方式允许通过HTTP接口触发WebSocket消息推送,实现了HTTP到WebSocket的消息转发,可以满足各种实时消息推送场景的需求。
许可协议:
CC BY 4.0