استرجاع شبكة أمان موقع السائق (انحدارة من الالتزام ab3be7e2):
- كان شرط "Smart Mode" يتخطّى _startDriverLocationPollingWithTimer كلياً إذا
جاء القبول من السوكيت. قبل إصلاح ترتيب الاتصال كان السوكيت يخسر دائماً
فالـ polling يعمل ويحمل الموقع؛ وبعد أن صار يفوز تعطّلت شبكة الأمان.
- وصول حدث القبول لا يعني أن تدفّق المواقع يعمل: التدفّق له شرط مستقل —
تطبيق السائق يحقن passenger_id في update_location فقط إذا كان rideStatus
نشطاً و BoxName.passengerID مكتوباً، وهو لا يُكتب إلا بعد فتح صفحة خريطة
السائق (map_driver_controller.dart:2444).
- الآن الـ polling يعمل دائماً، و handleDriverLocationUpdate يوقفه تلقائياً
بعد 3 تحديثات ناجحة من السوكيت — وهذا المنطق كان موجوداً أصلاً وهو التصميم
المقصود. السوكيت يبقى المسار السريع بلا فقدان شبكة الأمان.
عدم تعطيل إنشاء الرحلة بانتظار سوكيت غير قابل للوصول:
- ensureConnectedBeforeRide كانت تنتظر 4 ثوانٍ قبل كل طلب. سوكيتات
Workerman تستمع نصّاً صريحاً على 2020/3030 بينما التطبيقان يستخدمان
https:// عليها (nginx لا يمرّرها — انظر docker/nginx/default.conf)، فمصافحة
TLS ضد منفذ غير TLS تتجمّد حتى المهلة ⇒ 4 ثوانٍ مهدورة في كل رحلة.
- المهلة صارت 2ث، وأُضيف cooldown دقيقتين: بعد فشل قريب لا ننتظر إطلاقاً بل
نحاول الاتصال في الخلفية ونكمل الطلب فوراً.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
كان السوكيت مضموناً أن يخسر السباق الأول بنيوياً. ترتيب
startSearchingForDriver كان:
① await postRideDetailsToServer() → add_ride.php يوزّع الطلب على الكباتن فوراً
② _addRideToWaitingTable() (بلا await)
③ initConnectionWithSocket() ← السوكيت يبدأ الاتصال الآن فقط
بين ① و③ نافذة = ذهاب/عودة HTTP + مصافحة WebSocket + قراءة الـ JWT، ثانية
إلى ثلاث (أسوأ على 3G). وغرف Socket.IO لا تخزّن الأحداث: لو قبل كابتن داخل
تلك النافذة فإن $io->to('passenger_X')->emit() يُرمى نهائياً لأن الغرفة
فارغة — لا طابور ولا إعادة إرسال. وكابتن ينظر لقائمة السوق يقبل في أقل من
ثانية، فالنافذة مُرجَّحة لا نادرة.
هذا يفسّر لماذا كان الـ 404 على getRideOrderID.php قاتلاً: السوكيت يخسر،
والـ FCM يصل بعد أن ضبط الـ polling _isAcceptanceProcessed=true فيُرفض،
والشبكة الاحتياطية الوحيدة مكسورة.
ترتيب السيرفر كان صحيحاً أصلاً (acceptRide.php ينادي
notifyPassengerOnRideServer قبل sendFCM_Internal) — المشكلة أن المستقبِل
لم يكن موجوداً بعد.
التغييرات:
- ensureConnectedBeforeRide(): يوصل وينتظر الانضمام للغرفة بسقف 4 ثوانٍ،
ولا يُفشل إنشاء الرحلة عند انتهاء المهلة (نكمل ونتّكل على FCM/polling).
- startSearchingForDriver ينتظرها قبل postRideDetailsToServer.
- وصل السوكيت في initializeDataAfterLogin (عند فتح الخريطة) فيصير الانتظار
صفراً عملياً في الحالة الطبيعية.
- _isConnecting يغطّي نافذة الـ await على الـ JWT حتى لا يفتح النداءان
المتزامنان سوكيتين، وحرس على passengerID الفارغ.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>