19
This commit is contained in:
@@ -143,7 +143,7 @@ function forwardLocationToPassengerSocket(
|
|||||||
|
|
||||||
$http = new AsyncHttp();
|
$http = new AsyncHttp();
|
||||||
$http->request(
|
$http->request(
|
||||||
'http://rides.intaleq.xyz:3031',
|
'http://127.0.0.1:3031',
|
||||||
[
|
[
|
||||||
'method' => 'POST',
|
'method' => 'POST',
|
||||||
'data' => http_build_query([
|
'data' => http_build_query([
|
||||||
@@ -456,8 +456,8 @@ $io->on('connection', function ($socket) use ($INTERNAL_KEY) {
|
|||||||
forwardLocationToPassengerSocket(
|
forwardLocationToPassengerSocket(
|
||||||
$driverId, $passengerId,
|
$driverId, $passengerId,
|
||||||
[
|
[
|
||||||
'lat' => $lat,
|
'latitude' => $lat,
|
||||||
'lng' => $lng,
|
'longitude' => $lng,
|
||||||
'heading' => $heading,
|
'heading' => $heading,
|
||||||
'speed' => $speed,
|
'speed' => $speed,
|
||||||
'ride_id' => $rideId,
|
'ride_id' => $rideId,
|
||||||
|
|||||||
57
env_test.php
Normal file
57
env_test.php
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
// env_test.php - أداة مخصصة لاختبار جميع متغيرات البيئة
|
||||||
|
require_once __DIR__ . '/core/bootstrap.php'; // لتحميل الـ .env
|
||||||
|
|
||||||
|
header('Content-Type: text/plain; charset=utf-8');
|
||||||
|
|
||||||
|
echo "=== فحص متغيرات البيئة (Environment Variables) ===\n\n";
|
||||||
|
|
||||||
|
$keysToCheck = [
|
||||||
|
'PASSENGER_SOCKET_URL',
|
||||||
|
'LOCATION_SOCKET_URL',
|
||||||
|
'INTERNAL_SOCKET_KEY_PATH',
|
||||||
|
'SECRET_KEY_PAY_PATH',
|
||||||
|
'SECRET_KEY_HMAC',
|
||||||
|
'allowed1',
|
||||||
|
'allowed2',
|
||||||
|
'passwordnewpassenger',
|
||||||
|
'FP_PEPPER'
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($keysToCheck as $key) {
|
||||||
|
$val = getenv($key);
|
||||||
|
if ($val !== false && $val !== '') {
|
||||||
|
// إخفاء جزء من القيم الحساسة مثل كلمات المرور
|
||||||
|
if (strpos(strtolower($key), 'password') !== false || strpos(strtolower($key), 'secret') !== false || strpos(strtolower($key), 'hmac') !== false) {
|
||||||
|
$hiddenVal = substr($val, 0, 3) . '***' . substr($val, -3);
|
||||||
|
echo "[OK] $key = $hiddenVal\n";
|
||||||
|
} else {
|
||||||
|
echo "[OK] $key = $val\n";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo "[ERROR] $key = (مفقود أو فارغ!)\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "\n\n=== فحص الملفات المباشرة ===\n\n";
|
||||||
|
|
||||||
|
$filesToCheck = [
|
||||||
|
'/home/intaleq-api/.internal_socket_key',
|
||||||
|
'/home/intaleq-api/.secret_key_pay'
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($filesToCheck as $file) {
|
||||||
|
if (file_exists($file)) {
|
||||||
|
$content = trim(file_get_contents($file));
|
||||||
|
if (!empty($content)) {
|
||||||
|
$hidden = substr($content, 0, 3) . '***' . substr($content, -3);
|
||||||
|
echo "[OK] File ($file) exists and has content: $hidden\n";
|
||||||
|
} else {
|
||||||
|
echo "[WARNING] File ($file) exists but is EMPTY!\n";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo "[ERROR] File ($file) DOES NOT EXIST!\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "\n=== انتهى الفحص ===\n";
|
||||||
@@ -22,8 +22,8 @@ $INTERNAL_KEY = trim(file_get_contents(getenv('INTERNAL_SOCKET_KEY_PATH')));
|
|||||||
|
|
||||||
function sendToLocationServer($action, $data) {
|
function sendToLocationServer($action, $data) {
|
||||||
// رابط سيرفر اللوكيشن الداخلي أو العام
|
// رابط سيرفر اللوكيشن الداخلي أو العام
|
||||||
$url = getenv('LOCATION_SOCKET_URL');
|
$url = "http://188.68.36.205:2021";
|
||||||
$INTERNAL_KEY = trim(file_get_contents(getenv('INTERNAL_SOCKET_KEY_PATH')));
|
$INTERNAL_KEY = trim((string)@file_get_contents('/home/intaleq-api/.internal_socket_key'));
|
||||||
|
|
||||||
$postData = [
|
$postData = [
|
||||||
'action' => $action,
|
'action' => $action,
|
||||||
@@ -43,8 +43,8 @@ function sendToLocationServer($action, $data) {
|
|||||||
|
|
||||||
function findBestDrivers($con, $lat, $lng, $carType) {
|
function findBestDrivers($con, $lat, $lng, $carType) {
|
||||||
// 1. الاتصال بـ Redis لجلب الأقرب
|
// 1. الاتصال بـ Redis لجلب الأقرب
|
||||||
$locationServerUrl = getenv('LOCATION_API_URL');
|
$locationServerUrl = "https://location.intaleq.xyz/api_get_nearby.php";
|
||||||
$INTERNAL_KEY = trim(file_get_contents(getenv('INTERNAL_SOCKET_KEY_PATH')));
|
$INTERNAL_KEY = trim((string)@file_get_contents('/home/intaleq-api/.internal_socket_key'));
|
||||||
|
|
||||||
$postData = ['lat' => $lat, 'lng' => $lng, 'radius' => 5, 'limit' => 100];
|
$postData = ['lat' => $lat, 'lng' => $lng, 'radius' => 5, 'limit' => 100];
|
||||||
|
|
||||||
@@ -242,9 +242,12 @@ function notifyPassengerOnRideServer($passenger_id, $payload) {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$response = curl_exec($ch);
|
$response = curl_exec($ch);
|
||||||
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
|
|
||||||
if (curl_errno($ch)) {
|
if (curl_errno($ch)) {
|
||||||
error_log("Curl Error (Passenger Socket): " . curl_error($ch));
|
error_log("[SOCKET_DEBUG] Curl Error (Passenger Socket) to $url: " . curl_error($ch));
|
||||||
|
} else {
|
||||||
|
error_log("[SOCKET_DEBUG] Sent to Passenger Socket $url | HTTP: $httpCode | Response: $response | Passenger: $passenger_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
curl_close($ch);
|
curl_close($ch);
|
||||||
@@ -261,11 +264,9 @@ function dispatchRideToDrivers($driversData, $rideId, $payloadTemplate, $startNa
|
|||||||
$countDrivers = count($driversData);
|
$countDrivers = count($driversData);
|
||||||
error_log("🚀 [DISPATCH_START] RideID: $rideId | Drivers Count: $countDrivers");
|
error_log("🚀 [DISPATCH_START] RideID: $rideId | Drivers Count: $countDrivers");
|
||||||
|
|
||||||
$socketUrl = getenv('LOCATION_SOCKET_URL');
|
$socketUrl = 'http://188.68.36.205:2021';
|
||||||
if (!$socketUrl) throw new RuntimeException('LOCATION_SOCKET_URL not configured');
|
$internalKeyPath = '/home/intaleq-api/.internal_socket_key';
|
||||||
|
$internalKey = file_exists($internalKeyPath) ? trim((string)@file_get_contents($internalKeyPath)) : '';
|
||||||
$internalKeyPath = getenv('INTERNAL_SOCKET_KEY_PATH');
|
|
||||||
$internalKey = file_exists($internalKeyPath) ? trim(file_get_contents($internalKeyPath)) : '';
|
|
||||||
|
|
||||||
foreach ($driversData as $driver) {
|
foreach ($driversData as $driver) {
|
||||||
$driverId = $driver['driver_id'];
|
$driverId = $driver['driver_id'];
|
||||||
|
|||||||
@@ -76,8 +76,7 @@ try {
|
|||||||
'jti' => bin2hex(random_bytes(16)),
|
'jti' => bin2hex(random_bytes(16)),
|
||||||
];
|
];
|
||||||
|
|
||||||
$keyPathPay = getenv('SECRET_KEY_PAY_PATH');
|
$secretKey = trim((string)@file_get_contents('/home/intaleq-api/.secret_key_pay'));
|
||||||
$secretKey = trim(file_get_contents($keyPathPay));
|
|
||||||
$jwt = Firebase\JWT\JWT::encode($payload, $secretKey, 'HS256');
|
$jwt = Firebase\JWT\JWT::encode($payload, $secretKey, 'HS256');
|
||||||
|
|
||||||
$hmac = hash_hmac('sha256', $id, getenv('SECRET_KEY_HMAC'));
|
$hmac = hash_hmac('sha256', $id, getenv('SECRET_KEY_HMAC'));
|
||||||
|
|||||||
@@ -4,13 +4,6 @@
|
|||||||
* =====================
|
* =====================
|
||||||
* WebSocket Server للركاب — بورت 3030
|
* WebSocket Server للركاب — بورت 3030
|
||||||
* Internal HTTP Server — بورت 3031
|
* Internal HTTP Server — بورت 3031
|
||||||
*
|
|
||||||
* الإصلاحات عن النسخة السابقة:
|
|
||||||
* 1. إصلاح بنية الـ closures:
|
|
||||||
* كان update_driver_location خارج الـ onMessage callback → لا يُنفَّذ أبداً
|
|
||||||
* 2. تحليل الـ payload بشكل صحيح (json_decode للـ nested objects)
|
|
||||||
* 3. Heartbeat يُعاد تشغيله تلقائياً عند إعادة الاتصال
|
|
||||||
* 4. تنظيف البنية العامة
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use Workerman\Worker;
|
use Workerman\Worker;
|
||||||
@@ -18,10 +11,32 @@ use PHPSocketIO\SocketIO;
|
|||||||
|
|
||||||
require_once __DIR__ . '/vendor/autoload.php';
|
require_once __DIR__ . '/vendor/autoload.php';
|
||||||
|
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
// نظام تسجيل الأحداث (Logging System)
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
$LOG_FILE = __DIR__ . '/socket_debug.log';
|
||||||
|
|
||||||
|
function socket_log($message, $data = null) {
|
||||||
|
global $LOG_FILE;
|
||||||
|
$date = date('Y-m-d H:i:s');
|
||||||
|
$logMsg = "[$date] $message";
|
||||||
|
if ($data !== null) {
|
||||||
|
$logMsg .= " | DATA: " . (is_string($data) ? $data : json_encode($data, JSON_UNESCAPED_UNICODE));
|
||||||
|
}
|
||||||
|
$logMsg .= PHP_EOL;
|
||||||
|
|
||||||
|
echo $logMsg; // للطباعة في الكونسول إذا كان يعمل في الـ Foreground
|
||||||
|
@file_put_contents($LOG_FILE, $logMsg, FILE_APPEND); // الكتابة في الملف
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
|
||||||
|
socket_log("=== STARTING PASSENGER SOCKET SERVER ===");
|
||||||
|
|
||||||
$INTERNAL_KEY = trim((string) @file_get_contents('/home/intaleq-rides/.internal_socket_key'));
|
$INTERNAL_KEY = trim((string) @file_get_contents('/home/intaleq-rides/.internal_socket_key'));
|
||||||
|
|
||||||
if (empty($INTERNAL_KEY)) {
|
if (empty($INTERNAL_KEY)) {
|
||||||
echo '[CRITICAL] Internal key missing! Exiting.' . PHP_EOL;
|
socket_log("[CRITICAL_ERROR] Internal key missing! Exiting.");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,7 +52,10 @@ $io->on('workerStart', function () use ($io, $INTERNAL_KEY, $INTERNAL_PORT) {
|
|||||||
$innerHttp->onMessage = function ($connection, $request) use ($io, $INTERNAL_KEY) {
|
$innerHttp->onMessage = function ($connection, $request) use ($io, $INTERNAL_KEY) {
|
||||||
|
|
||||||
$headers = $request->header();
|
$headers = $request->header();
|
||||||
|
$clientIp = $connection->getRemoteIp();
|
||||||
|
|
||||||
if (($headers['x-internal-key'] ?? '') !== $INTERNAL_KEY) {
|
if (($headers['x-internal-key'] ?? '') !== $INTERNAL_KEY) {
|
||||||
|
socket_log("[HTTP_ERROR] Unauthorized internal request from IP: $clientIp");
|
||||||
$connection->send('Unauthorized');
|
$connection->send('Unauthorized');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -51,6 +69,7 @@ $io->on('workerStart', function () use ($io, $INTERNAL_KEY, $INTERNAL_PORT) {
|
|||||||
$rawPayload = $post['payload'] ?? null;
|
$rawPayload = $post['payload'] ?? null;
|
||||||
|
|
||||||
if (!$passengerId || !$rawPayload) {
|
if (!$passengerId || !$rawPayload) {
|
||||||
|
socket_log("[HTTP_ERROR] Missing passenger_id or payload for action: update_ride_status", $post);
|
||||||
$connection->send('Error: Missing passenger_id or payload');
|
$connection->send('Error: Missing passenger_id or payload');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -59,10 +78,10 @@ $io->on('workerStart', function () use ($io, $INTERNAL_KEY, $INTERNAL_PORT) {
|
|||||||
? (json_decode($rawPayload, true) ?? $rawPayload)
|
? (json_decode($rawPayload, true) ?? $rawPayload)
|
||||||
: $rawPayload;
|
: $rawPayload;
|
||||||
|
|
||||||
|
socket_log("[HTTP_SUCCESS] Emitting 'ride_status_change' to Passenger #$passengerId", $payload);
|
||||||
$io->to('passenger_' . $passengerId)->emit('ride_status_change', $payload);
|
$io->to('passenger_' . $passengerId)->emit('ride_status_change', $payload);
|
||||||
|
|
||||||
$connection->send('OK');
|
$connection->send('OK');
|
||||||
echo '[' . date('H:i:s') . '] Status update sent to Passenger #' . $passengerId . PHP_EOL;
|
|
||||||
|
|
||||||
} elseif ($action === 'update_driver_location') {
|
} elseif ($action === 'update_driver_location') {
|
||||||
|
|
||||||
@@ -70,6 +89,7 @@ $io->on('workerStart', function () use ($io, $INTERNAL_KEY, $INTERNAL_PORT) {
|
|||||||
$rawPayload = $post['payload'] ?? null;
|
$rawPayload = $post['payload'] ?? null;
|
||||||
|
|
||||||
if (!$passengerId || !$rawPayload) {
|
if (!$passengerId || !$rawPayload) {
|
||||||
|
socket_log("[HTTP_ERROR] Missing passenger_id or payload for action: update_driver_location", $post);
|
||||||
$connection->send('Error: Missing passenger_id or payload');
|
$connection->send('Error: Missing passenger_id or payload');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -78,38 +98,43 @@ $io->on('workerStart', function () use ($io, $INTERNAL_KEY, $INTERNAL_PORT) {
|
|||||||
? (json_decode($rawPayload, true) ?? $rawPayload)
|
? (json_decode($rawPayload, true) ?? $rawPayload)
|
||||||
: $rawPayload;
|
: $rawPayload;
|
||||||
|
|
||||||
|
socket_log("[HTTP_SUCCESS] Emitting 'driver_location_update' to Passenger #$passengerId", $payload);
|
||||||
$io->to('passenger_' . $passengerId)->emit('driver_location_update', $payload);
|
$io->to('passenger_' . $passengerId)->emit('driver_location_update', $payload);
|
||||||
|
|
||||||
$connection->send('OK');
|
$connection->send('OK');
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
socket_log("[HTTP_WARNING] Unknown action received: $action", $post);
|
||||||
$connection->send('Unknown action: ' . $action);
|
$connection->send('Unknown action: ' . $action);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$innerHttp->listen();
|
$innerHttp->listen();
|
||||||
echo '[' . date('H:i:s') . "] Internal HTTP started on port $INTERNAL_PORT" . PHP_EOL;
|
socket_log("[INFO] Internal HTTP started on port $INTERNAL_PORT");
|
||||||
});
|
});
|
||||||
|
|
||||||
$io->on('connection', function ($socket) {
|
$io->on('connection', function ($socket) {
|
||||||
|
|
||||||
$query = $socket->handshake['query'] ?? [];
|
$query = $socket->handshake['query'] ?? [];
|
||||||
$passengerId = $query['id'] ?? null;
|
$passengerId = $query['id'] ?? null;
|
||||||
|
$clientIp = $socket->conn->remoteAddress ?? 'Unknown';
|
||||||
|
|
||||||
if (!$passengerId) {
|
if (!$passengerId) {
|
||||||
|
socket_log("[SOCKET_REJECTED] Connection rejected (No passenger ID) from IP: $clientIp");
|
||||||
$socket->disconnect();
|
$socket->disconnect();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$socket->join('passenger_' . $passengerId);
|
$socket->join('passenger_' . $passengerId);
|
||||||
echo '[' . date('H:i:s') . "] Passenger Connected: #$passengerId" . PHP_EOL;
|
socket_log("[SOCKET_CONNECTED] Passenger Connected: #$passengerId (IP: $clientIp)");
|
||||||
|
|
||||||
$socket->on('heartbeat', function ($data) {
|
$socket->on('heartbeat', function ($data) {
|
||||||
// استقبال النبضة فقط — لا يحتاج رد
|
// يمكن تفعيل السطر التالي للتأكد من النبضات إذا أردت دقة شديدة، لكنه قد يملأ ملف الـ log
|
||||||
|
// socket_log("[SOCKET_HEARTBEAT] Received from Passenger #$passengerId");
|
||||||
});
|
});
|
||||||
|
|
||||||
$socket->on('disconnect', function () use ($passengerId) {
|
$socket->on('disconnect', function () use ($passengerId, $clientIp) {
|
||||||
echo '[' . date('H:i:s') . "] Passenger Disconnected: #$passengerId" . PHP_EOL;
|
socket_log("[SOCKET_DISCONNECTED] Passenger Disconnected: #$passengerId (IP: $clientIp)");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -160,13 +160,13 @@ try {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FCM — push notification
|
// FCM — push notification صامت
|
||||||
if (!empty($passengerToken)) {
|
if (!empty($passengerToken)) {
|
||||||
sendFCM_Internal(
|
sendFCM_Internal(
|
||||||
$passengerToken,
|
$passengerToken,
|
||||||
"تم قبول رحلتك",
|
"", // تفريغ العنوان للإرسال الصامت
|
||||||
"الكابتن " . ($driverInfo['driverName'] ?? '') . " في طريقه إليك",
|
"", // تفريغ المحتوى للإرسال الصامت
|
||||||
['ride_id' => (string) $rideId, 'driver_info' => $driverInfo],
|
['ride_id' => (string) $rideId, 'driver_info' => $driverInfo, 'status' => 'accepted'],
|
||||||
"Accepted Ride",
|
"Accepted Ride",
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -54,11 +54,11 @@ try {
|
|||||||
'ride_id' => (string)$rideId
|
'ride_id' => (string)$rideId
|
||||||
];
|
];
|
||||||
|
|
||||||
// 🔥 استخدام sendFCM_Internal
|
// 🔥 استخدام sendFCM_Internal كرسالة صامتة
|
||||||
sendFCM_Internal(
|
sendFCM_Internal(
|
||||||
$passengerToken, // الهدف
|
$passengerToken, // الهدف
|
||||||
"السائق وصل 📍", // العنوان
|
"", // تفريغ العنوان
|
||||||
"الكابتن ينتظرك في الموقع المحدد.", // النص
|
"", // تفريغ النص
|
||||||
$fcmData, // البيانات
|
$fcmData, // البيانات
|
||||||
"Arrive Ride", // التصنيف
|
"Arrive Ride", // التصنيف
|
||||||
false // ليس Topic
|
false // ليس Topic
|
||||||
|
|||||||
@@ -78,13 +78,13 @@ try {
|
|||||||
'ride_id' => (string)$ride_id
|
'ride_id' => (string)$ride_id
|
||||||
];
|
];
|
||||||
|
|
||||||
// 🔥 استخدام sendFCM_Internal
|
// 🔥 استخدام sendFCM_Internal كرسالة صامتة
|
||||||
sendFCM_Internal(
|
sendFCM_Internal(
|
||||||
$passengerToken, // الهدف
|
$passengerToken, // الهدف
|
||||||
"بدأت الرحلة 🏁", // العنوان
|
"", // تفريغ العنوان
|
||||||
"نتمنى لك رحلة آمنة ومريحة.", // النص
|
"", // تفريغ النص
|
||||||
$fcmData, // البيانات
|
$fcmData, // البيانات
|
||||||
"Trip is Begin", // التصنيف (حافظنا عليه كما هو في التطبيق)
|
"Trip is Begin", // التصنيف
|
||||||
false // ليس Topic
|
false // ليس Topic
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user