diff --git a/loction_server/driver_socket.php b/loction_server/driver_socket.php index 86c46d4e..f90acbb6 100755 --- a/loction_server/driver_socket.php +++ b/loction_server/driver_socket.php @@ -743,10 +743,18 @@ $io->on('connection', function ($socket) use ($INTERNAL_KEY) { } $socket->join('driver_' . $driverId); + + // ‏نحفظ معرّف السوكيت مع السجلّ: التطبيق يفتح أكثر من اتصال للسائق نفسه + // ‏(location_controller و background_service ومحاولات لم تُنظَّف)، وحين يُغلق + // ‏أحدها كان معالج disconnect يمحو السائق من السجلّ كاملاً بينما البقية + // ‏متصلة — فيعتبره dispatch_order غير متصل ويضع الطلب في طابور الانتظار، + // ‏ويظهر في اللوج «notified 0/0 driver(s)». + $socketId = $socket->id; $connectedDrivers[$driverId] = [ 'conn' => $socket, 'platform' => $platform, 'token' => $fcmToken, + 'sid' => $socketId, ]; if (!isset($driverState[$driverId])) { @@ -837,6 +845,21 @@ $io->on('connection', function ($socket) use ($INTERNAL_KEY) { if ($lat === null || $lng === null) return; + // ‏حرس: لو حُذفت الحالة (إغلاق سوكيت آخر لنفس السائق، أو إعادة تشغيل) + // ‏فإن ‎&$driverState[$driverId]‎ يُنشئ مدخلاً null فتقرأ كل الأسطر التالية + // ‏من null — وهذا مصدر تحذيرات «array offset on value of type null» في + // ‏الأسطر 860‑872 و«Undefined array key status» في 907. + if (!isset($driverState[$driverId]) || !is_array($driverState[$driverId])) { + $driverState[$driverId] = [ + 'lat' => 0.0, + 'lng' => 0.0, + 'speed' => -999.0, + 'heading' => -999.0, + 'status' => '', + 'expire_ts' => 0, + ]; + } + $state = &$driverState[$driverId]; $now = time(); @@ -996,9 +1019,19 @@ $io->on('connection', function ($socket) use ($INTERNAL_KEY) { ], $INTERNAL_KEY, $busFwdThrottle); }); - $socket->on('disconnect', function () use ($driverId) { + $socket->on('disconnect', function () use ($driverId, $socketId) { global $connectedDrivers, $driverState, $fwdThrottle; + // ‏لا ننظّف إلا إذا كان المُغلَق هو السوكيت المسجَّل حالياً. الجهاز يفتح + // ‏عدة اتصالات للسائق نفسه، وتنظيف السجلّ عند إغلاق نسخة قديمة كان + // ‏يُطفئ السائق فعلياً وهو متصل: التوزيع يراه offline، و update_location + // ‏من السوكيت الحيّ يجد $driverState محذوفاً فتظهر تحذيرات null. + $registeredSid = $connectedDrivers[$driverId]['sid'] ?? null; + if ($registeredSid !== null && $registeredSid !== $socketId) { + logMsg("↩️ Stale duplicate socket closed for #$driverId — registry kept."); + return; + } + unset($connectedDrivers[$driverId]); unset($driverState[$driverId]); unset($fwdThrottle[$driverId]);