环境什么都相同,只是更换了一台服务器,运行则出现这个问题,原服务器跟这个一样的。
SendBufferToWorker fail. The connections between Gateway and BusinessWorker are not ready
--------------------start_gateway.php--------------------
<?php
require_once __DIR__ . '/vendor/autoload.php';
use GatewayWorker\Gateway;
use Workerman\Worker;
// 初始化 Gateway
$gateway = new Gateway("websocket://0.0.0.0:3301");
// 设置进程数
$gateway->count = 4;
// 设置名称
$gateway->name = 'WebSocketGateway';
// 设置心跳检测
$gateway->pingInterval = 30;
$gateway->pingNotResponseLimit = 1;
--------------------start_businessworker.php--------------------
<?php
require_once __DIR__ . '/vendor/autoload.php';
use GatewayWorker\BusinessWorker;
use Workerman\Worker;
// 初始化 BusinessWorker
$worker = new BusinessWorker();
// 设置名称
$worker->name = 'WebSocketBusinessWorker';
// 设置进程数
$worker->count = 4;
// 设置事件处理类
$worker->eventHandler = 'Events';
--------------------start_http.php--------------------
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
use Workerman\Protocols\Http\Response;
use GatewayWorker\Lib\Gateway;
// 创建 Redis 客户端
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
// 创建一个 HTTP 服务器,监听 3300 端口
$httpWorker = new Worker('http://0.0.0.0:3300');
// 监听 HTTP 请求事件
$httpWorker->onMessage = function (TcpConnection $connection, Request $request) use ($redis) {
// 检查请求方法是否为 POST
if ($request->method() === 'POST') {
// 获取请求体中的 JSON 数据
$data = json_decode($request->rawBody(), true);
// 检查 JSON 数据是否解析成功
if (json_last_error() === JSON_ERROR_NONE) {
// 获取请求路径(例如 /pudm)
$path = $request->path();
// 从 Redis 中获取该路径对应的客户端 ID
$clientIds = $redis->get($path);
if (!empty($clientIds)) {
Gateway::sendToGroup($path, $request->rawBody());
// 返回成功响应
$connection->send(new Response(200, [], json_encode([
'status' => 'success',
'message' => 'Message forwarded to WebSocket clients'
])));
} else {
// 没有客户端连接该路径
$connection->send(new Response(404, [], json_encode([
'status' => 'error',
'message' => 'No clients connected to this path'
])));
}
} else {
// JSON 解析失败
$connection->send(new Response(400, [], json_encode([
'status' => 'error',
'message' => 'Invalid JSON data'
])));
}
} else {
// 非 POST 请求
$connection->send(new Response(405, [], json_encode([
'status' => 'error',
'message' => 'Only POST requests are allowed'
])));
}
};
--------------------start_register.php--------------------
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
// 初始化 Register
$register = new Worker('text://0.0.0.0:1237');
// 设置名称
$register->name = 'Register';
--------------------Events.php--------------------
<?php
require_once __DIR__ . '/vendor/autoload.php';
use GatewayWorker\Lib\Gateway;
use Workerman\Connection\TcpConnection;
// 创建 Redis 客户端
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
class Events
{
// 当客户端连接时触发
public static function onConnect($clientId)
{
echo "Client {$clientId} connected.\n";
}
// 当客户端发送消息时触发
public static function onMessage($clientId, $message)
{
echo "Received message from client {$clientId}: {$message}\n";
Gateway::sendToAll($message, null, $clientId);
}
// 当客户端断开连接时触发
public static function onClose($clientId)
{
echo "Client {$clientId} disconnected.\n";
// 从 Redis 中移除该客户端 ID
global $redis;
$paths = $redis->keys('*');
foreach ($paths as $path) {
$redis->sRem($path, $clientId);
}
}
// 当 WebSocket 握手成功时触发
public static function onWebSocketConnect($clientId, $httpHeader)
{
// 从 HTTP 请求头中提取路径
$path = $httpHeader['server']['REQUEST_URI'];
Gateway::joinGroup($clientId, $path);
global $redis;
$redis->set($path, $clientId);
}
// 从 HTTP 请求头中提取路径
private static function extractPathFromHeader($httpHeader)
{
// 查找路径的开始位置
$start = strpos($httpHeader, 'GET /') + 4;
// 查找路径的结束位置
$end = strpos($httpHeader, ' HTTP/1.1');
// 提取路径
return substr($httpHeader, $start, $end - $start);
}
}
PHP版本:8.0.26
端口均已放行
额,没人吗
这种一般都是防火墙端口未放行问题
端口都放了的
检查一下服务器的安全组有没有放行端口
服务器也放了
求助,困扰一下午了
是云服务器吗? 云端安全组也需要放行
都放行了,全端口放行。
求助,求助
registerAddress没配置,
$gateway->registerAddress = '127.0.0.1:1237';
$worker->registerAddress = '127.0.0.1:1237';
另外redis和数据库等初始化放到onWorkerStart里,提前初始化后所有子进程共享redis和数据库连接导致连接断开或数据错乱
我试试,感谢。
似乎还是不行,registerAddress在gateway和BusinessWorker里面均进行了配置,并且把redis放在onworkerstart里面初始化了,似乎还是这个结果
滴滴
额,没人吗