Update: 2026-07-04 16:47:10

This commit is contained in:
Hamza-Ayed
2026-07-04 16:47:11 +03:00
parent c8fdd1bb5a
commit 838e5ec656
4 changed files with 534 additions and 2 deletions
+86 -2
View File
@@ -302,8 +302,28 @@ $io->on('workerStart', function () use ($io, $INTERNAL_KEY) {
logMsg("🚀 Dispatch Ride #$rideId → " . count($drivers) . ' drivers.');
}
// 🆕 Ride Offer Cache + Pending Queue (للتعافي من انقطاع الاتصال)
if ($redis && $rideId && !empty($payload)) {
$offerKey = "ride:offer:$rideId";
$offerTtl = 120;
$redis->setex($offerKey, $offerTtl, json_encode($payload));
$offeredSetKey = "ride:offered_drivers:$rideId";
$redis->sadd($offeredSetKey, ...$drivers);
$redis->expire($offeredSetKey, $offerTtl);
}
foreach ($drivers as $driverId) {
if (!isset($connectedDrivers[$driverId])) continue;
if (!isset($connectedDrivers[$driverId])) {
// السائق غير متصل → نخزن في قائمة الانتظار عشان يسلمله أول ما يوصل
if ($redis && $rideId) {
$pendingKey = "driver:pending_orders:$driverId";
$redis->zadd($pendingKey, time(), $rideId);
$redis->expire($pendingKey, 120);
}
logMsg("📦 Driver #$driverId offline — saved to pending queue.");
continue;
}
$io->to('driver_' . $driverId)->emit('new_ride_request', $payload);
$platform = $connectedDrivers[$driverId]['platform'] ?? 'android';
@@ -376,7 +396,18 @@ $io->on('workerStart', function () use ($io, $INTERNAL_KEY) {
if (!$rideId) { $connection->send('Error: Missing ride_id'); return; }
if ($redis) $redis->zrem('geo:rides:waiting', $rideId);
if ($redis) {
$redis->zrem('geo:rides:waiting', $rideId);
// 🆕 Clean pending offers from all drivers' queues
$offeredSetKey = "ride:offered_drivers:$rideId";
$offeredDrivers = $redis->smembers($offeredSetKey);
foreach ($offeredDrivers as $dId) {
$redis->zrem("driver:pending_orders:$dId", $rideId);
}
$redis->del($offeredSetKey);
$redis->del("ride:offer:$rideId");
}
$io->emit('ride_taken', [
'ride_id' => $rideId,
@@ -480,10 +511,63 @@ $io->on('connection', function ($socket) use ($INTERNAL_KEY) {
logMsg("✅ Driver Connected: #$driverId ($platform)");
// 🆕 Deliver any pending orders missed during disconnection
// نستخدم pipeline لتقليل عدد عمليات Redis (خفيف على السيرفر)
$redis = getRedis();
if ($redis) {
$pendingKey = "driver:pending_orders:$driverId";
$pendingRides = $redis->zrevrangebyscore($pendingKey, time(), time() - 120);
if (!empty($pendingRides)) {
$pipe = $redis->pipeline();
foreach ($pendingRides as $pRideId) {
$offerData = $redis->get("ride:offer:$pRideId");
if ($offerData) {
$decoded = json_decode($offerData, true);
if ($decoded) {
$socket->emit('new_ride_request', $decoded);
logMsg("📦 Re-delivered pending Ride #$pRideId to Driver #$driverId");
// نزيل الرحلة من قائمة الانتظار فوراً
// هذا يمنع إعادة الإرسال عند إعادة الاتصال مرة أخرى (شبكة ضعيفة)
$pipe->zrem($pendingKey, $pRideId);
}
} else {
$pipe->zrem($pendingKey, $pRideId);
}
}
$pipe->execute();
}
}
$socket->on('ping_alive', function () {
// Socket.IO handles pong automatically
});
// 🆕 Client requests any pending orders missed during disconnection
$socket->on('get_pending_orders', function () use ($driverId, $socket) {
$redis = getRedis();
if (!$redis) return;
$pendingKey = "driver:pending_orders:$driverId";
$pendingRides = $redis->zrevrangebyscore($pendingKey, time(), time() - 120);
if (empty($pendingRides)) return;
logMsg("📦 get_pending_orders: " . count($pendingRides) . " pending for Driver #$driverId");
$pipe = $redis->pipeline();
foreach ($pendingRides as $pRideId) {
$offerData = $redis->get("ride:offer:$pRideId");
if ($offerData) {
$decoded = json_decode($offerData, true);
if ($decoded) {
$socket->emit('new_ride_request', $decoded);
$pipe->zrem($pendingKey, $pRideId);
}
} else {
$pipe->zrem($pendingKey, $pRideId);
}
}
$pipe->execute();
});
$socket->on('update_location', function ($data)
use ($driverId, $INTERNAL_KEY, &$driverState, &$fwdThrottle, &$eventBuffer)
{