I'm always excited to take on new projects and collaborate with innovative minds.

Phone

+20 115 052 9992

Website

https://ibrahimahmed.online/

Social Links

إدارة الـ WebSockets واستقبال الـ Events اللحظية داخل مكونات Inertia: ودع الـ Reload للأبد

التصنيف: تطوير الويب (Web Development) - شروحات تقنية (Tutorials) إدارة الـ WebSockets واستقبال الـ Events اللحظية داخل مكونات Inertia: ودع الـ Reload للأبد يا

إدارة الـ WebSockets واستقبال الـ Events اللحظية داخل مكونات Inertia: ودع الـ Reload للأبد
Reading Count: 7

التصنيف: تطوير الويب (Web Development) - شروحات تقنية (Tutorials)

إدارة الـ WebSockets واستقبال الـ Events اللحظية داخل مكونات Inertia: ودع الـ Reload للأبد

يا هلا بيك يا صديقي المبرمج! كام مرة كنت قاعد بتكتب تطبيق ويب، والعميل أو الـ Product Manager جه قالك: "بص، أنا عايز أول ما البيانات تتغير في الداتابيز، الشاشة تحدث لوحدها عند كل المستخدمين من غير ما يعملوا Refresh لل頁ة؟" هنا قلبك بيدق سريع، وبتفكر: يا نهار أبيض، هو أنا لسه هندس سستم (System) كامل للـ WebSockets؟ ما أنا شغال بـ Inertia.js أصلاً، وعارف إن إنرشيا قايمة أساساً على فكرة الـ SPA (Single Page Application) بس ب backend تقليدي زي لارفال (Laravel)!

الموضوع زمان كان معقد، وكانت الناس تضطر تروح تبني API منفصل وتجيب وجع دماغ مع سرفرات زي Node.js و Socket.io عشان تعمل حتة Real-time بسيطة. بس النهاردة، ومع التطور الرهيب فيecosystem بتاع لارفال، وبالتحديد بعد ما طلع لنا Laravel Reverb، الدنيا بقت ألذ بكتير. في المقال ده، هناخد رحلة عملية خطوة بخطوة عشان نعرف إزاي ندير الـ WebSockets ونستقبل الأحداث اللحظية (Real-time Events) جوه مكونات إنرشيا بتاعتك، سواء كنت شغال بـ React أو Vue.js، وكل ده من غير ما تكتب سطر كود واحد يخلي الصفحة تعمل Reload مزعج.

إيه هو Laravel Reverb وليه بنحتاجه مع Inertia؟

زمان عشان نعمل اتصال حي (Real-time connection) بين السرفر والمتصفح، كنا بنضطر نعتمد على حزم خارجية زي Pusher (اللي ساعات بتبقى مكلفة في المشاريع الكبيرة) أو نرفع سرفر Laravel WebSockets القديم ونقعد نظبط في الـ Daemons والـ Supervisor. لكن لارفال وفرت علينا ده كله بـ Laravel Reverb، وهو السرفر الرسمي للـ WebSockets المصنوع خصيصاً للارفال عشان يكون فائق السرعة، خفيف، ومبني بلغة PHP (باستخدام Ratchet/Evenement تحت الكود) ومتكامل بشكل مرعب مع نظام الـ Broadcasting بتاع لارفال.

الجميلة هنا إن Inertia.js بتعتمد على الـ Page props اللي بتيجي من السرفر، ولمّا بـ تحب تحدث البيانات، الطبيعي إنك بتعمل Inertia.visit أو router.reload. بس مع الـ WebSockets، إحنا مش هنستنى المستخدم يدوس حاجة؛ إحنا هنسسمع للـ Events وهي طايحة في الجو، وأول ما تيجي، هنحدث الـ State المحلية بتاعة المكون (Component State) فوراً، أو هنعمل تحديث ذكي للـ props من غير ما نحسس المستخدم بأي لود.

الخطوة الأولى: تجهيز السرفر وتثبيت Laravel Reverb

عشان نبتدي نشتغل، لازم الأول نتأكد إن مشروع لارفال بتاعنا جاهز. افتح التيرمينال (Terminal) بتاعتك واكتب الأمر ده عشان تسطب Reverb:

php artisan install:broadcasting

الأمر السحري ده هيعمل كذا حاجة لوحده: هيسطب الحزمة، هيعمل publish لملف الإعدادات config/reverb.php، وهيعرفك بالمتغيرات اللي محتاج تضاف في ملف الـ .env بتاعك زي الـ App ID والKey والSecret. افتح ملف الـ .env واتأكد إن الدنيا مظبوطة كده:

BROADCAST_CONNECTION=reverb

REVERB_APP_ID=your-app-id
REVERB_APP_KEY=your-app-key
REVERB_APP_SECRET=your-app-secret
REVERB_HOST="localhost"
REVERB_PORT=8080
REVERB_SCHEME=http

VITE_REVERB_APP_KEY="${REVERB_APP_KEY}"
VITE_REVERB_HOST="${REVERB_HOST}"
VITE_REVERB_PORT="${REVERB_PORT}"
VITE_REVERB_SCHEME="${REVERB_SCHEME}"

بعد كده، هتروح تشغل سرفر الـ Reverb عندك على الجهاز بالأمر ده:

php artisan reverb:start

سيبه شغال في تيرمينال لوحده، ويلا بينا نروح نظبط الفرت إند (Frontend).

الخطوة الثانية: تجهيز الـ Frontend وإعداد Laravel Echo

بما إننا شغالين Inertia، فأكيد إحنا مستخدمين إما React أو Vue.js ومعاهم Vite. عشان نقدر نسمع للـ WebSockets من المتصفح، محتاجين نثبت مكتبتين أساسيتين: laravel-echo و pusher-js (متقلقش، pusher-js هنا بنستخدمها كـ Client عادي عشان تتصل بـ Reverb لأنه بيدعم نفس الـ Protocol):

npm install --save-dev laravel-echo pusher-js

دلوقتي، محتاجين نعرف لارافيل إحنا بنربط إزاي. افتح ملف resources/js/bootstrap.js (أو ملف الـ bootstrap اللي عندك حسب هيكلة المشروع)، واكتب الإعدادات دي:

import Echo from 'laravel-echo';
import Pusher from 'pusher-js';

window.Pusher = Pusher;

window.Echo = new Echo({
    broadcaster: 'reverb',
    key: import.meta.env.VITE_REVERB_APP_KEY,
    wsHost: import.meta.env.VITE_REVERB_HOST,
    wsPort: import.meta.env.VITE_REVERB_PORT,
    wssPort: import.meta.env.VITE_REVERB_PORT,
    forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'http') === 'https',
    enabledTransports: ['ws', 'wss'],
});

الخطوة الثالثة: ربط الأحداث داخل مكونات Inertia (مثال عملي)

تخيل إننا عاملين صفحة داشبورد (Dashboard) بـ Inertia، وعايزين نظهر فيها قائمة بالطلبات الجديدة (Orders) أول بأول. في البداية، الصفحة بتفتح بالـ Props العادية اللي راجعة من الكونترولر (Controller). بس عشان نخليها حية، هنستخدم الـ useEffect لو شغالين React، أو الـ onMounted لو شغالين Vue.

تعال نشوف مثال عملي بـ React:

import React, { useEffect, useState } from 'react';
import { Head } from '@inertiajs/react';

export default function Dashboard({ initialOrders }) {
    const [orders, setOrders] = useState(initialOrders);

    useEffect(() => {
        // الاشتراك في القناة العامة أو الخاصة
        window.Echo.channel('orders')
            .listen('.OrderCreated', (e) => {
                // لما يوصل إيفينت جديد، بنحدث الـ State فوراً من غير Reload
                setOrders((prevOrders) => [e.order, ...prevOrders]);
            });

        // تنظيف الاتصال لما المكون يقفل (Cleanup)
        return () => {
            window.Echo.leave('orders');
        };
    }, []);

    return (
        <div>
            <Head title="لوحة التحكم اللحظية" />
            <h1>الطلبات الواردة مباشرة</h1>
            <ul>
                {orders.map((order) => (
                    <li key={order.id}>
                        طلب رقم #{order.id} - العميل: {order.customer_name}
                    </li>
                ))}
            </ul>
        </div>
    );
}

أما لو كنت من عشاق Vue.js 3، فالكود هيكون مشابه جداً جوه الـ Setup Script:

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';

const props = defineProps({
    initialOrders: Array
});

const orders = ref(props.initialOrders);

onMounted(() => {
    window.Echo.channel('orders')
        .listen('.OrderCreated', (e) => {
            orders.value.unshift(e.order);
        });
});

onUnmounted(() => {
    window.Echo.leave('orders');
});
</script>

<template>
    <div>
        <h1>الطلبات الواردة مباشرة</h1>
        <ul>
            <li v-for="order in orders" :key="order.id">
                طلب رقم #{order.id} - العميل: {{ order.customer_name }}
            </li>
        </ul>
    </div>
</template>

نصائح ذهبية لإدارة الذاكرة والأداء (Performance & Memory Leaks)

لما تبدأ تدمج الـ WebSockets جوه تطبيقات الـ SPA زي Inertia، فيه نقطة حرجة جداً لازم تاخد بالك منها وهي الـ Memory Leaks (تسريب الذاكرة). لمّا المستخدم يتنقل بين الصفحات في Inertia، الصفحات القديمة بتتقفل والمكونات بتتحذف من الـ DOM، بس لو أنت عملت اتصال لـ Echo جوه الـ Component ومنفذتش دالة المغادرة (Leave/Unsubscribe)، الاتصال هيفضل مفتوح في الخلفية وكل ما المستخدم يتنقل، هتكتر الاتصالات وتلاقي التطبيق بقى بطيء جداً وبيستهلك رامات السرفر والمتصفح.

عشان كده، دايماً اتركب كود الـ Cleanup (زي window.Echo.leave() أو window.Echo.leaveChannel()) في الـ Unmount hook بتاعتك. نقطة تانية مهمة، لو بتستخدم قنوات خاصة (Private Channels) عشان أمان المستخدمين، تأكد إنك مظبط الـ routes/channels.php صح، وإن الـ CSRF Token والـ Sanctum/Session authentication شغالين تمام عشان الـ Authorization يعدي بسلام.

خاتمة: نصيحة من أخ

يا صاحبي، تقنيات الـ Real-time مبقتش رفاهية في سوق التوظيف أو في المشاريع الحديثة؛ دي بقت معيار أساسي عشان تدي المستخدم تجربة تخليه "يحس" بسلاسة التطبيق. ربط Laravel Reverb مع مكونات Inertia فتح باب كبير جداً قدامنا عشان نعمل تطبيقات قوية، سريعة، ومبتذتش الـ Backend في طلبات مكررة ملهاش لازمة. نصيحتي ليك: متخافش من التقنيات الجديدة، ابدأ طبقها حتى لو في مشروع تجريبي (Side Project) صغير، واغلط مرة واتنين لحد ما إيدك تخد على كتابة الكود النظيف والمنظم. بالتوفيق، ولو عندك أي استفسار، سيبه في الكومنتات!


Share

Related posts

Aug 09, 2026 • 3 min read
Reading Count: 3
ازاي تنظم الـ Layouts المتعددة (Dashboard vs Website) في مشروع Inertia واحد باحترافية

معرفات التصنيف: 1, 3 ازاي تنظم الـ Layouts المتعددة (Dashboard vs Website) في مشروع Inertia واحد باح...

Aug 09, 2026 • 3 min read
Reading Count: 5
حل مشكلة فقدان الـ Scroll Position عند التنقل في مشاريع Inertia الكبيرة

تخيل معايا السيناريو ده: قاعد بتفتح موقع كبير، مثلاً متجر إلكتروني أو تطبيق عقارات شغال بتطوير الويب...

Aug 08, 2026 • 3 min read
Reading Count: 10
ازاي تبني فلاتر بحث معقدة (Complex Filters) وتظبط الـ URL مع Inertia.js زي البروفيشنال

ازاي تبني فلاتر بحث معقدة (Complex Filters) وتظبط الـ URL مع Inertia.js زي البروفيشنال يا هلا بيك يا...