لماذا يتسبب تبرع واحد في ظهور تنبيهين بعد تحديث مصدر المتصفح
لماذا يتسبب تبرع واحد في ظهور تنبيهين
بعد تحديث مصدر المتصفح تُعاد الصفحة إلى العمل من جديد. يتصل السكربت بالخادم مرة أخرى، ويشترك في الأحداث، وينشئ معالجات لعرض الإشعارات. إذا لم يُزل المعالج القديم أو كان هناك اتصالان يعملان في الوقت نفسه، فإن حدث التبرع الواحد تتم معالجته عدة مرات.
التحديث نفسه ليس بالضرورة سبب العطل. غالبًا ما يكشف فقط عن خطأ في منطق الاتصال. على سبيل المثال، قد تُنفَّذ دالة التهيئة عند تحميل الصفحة، ثم عند استعادة الاتصال، ومرة أخرى بعد استلام رسالة خدمية. وكل تنفيذ يضيف اشتراكًا جديدًا في حدث donation.
نتيجة لذلك يرسل الخادم كائن تبرع واحدًا، لكن المتصفح يستدعي الدالة نفسها مرتين. أحيانًا يحدث التكرار على جانب الخادم: يعتبر التطبيق الاتصال الجديد مستقبلًا منفصلًا ويرسل الحدث إلى الجلسة القديمة والجلسة الجديدة معًا. لذلك يجب أولًا تحديد مكان ظهور التكرار: في المصدر أم في المعالج أم في مرحلة العرض.
كيف تجد الموضع الذي ينشأ فيه التكرار
ابدأ باختبار بسيط. افتح رابط مصدر المتصفح في نافذة أو تبويب منفصل، واترك نسخة واحدة فقط من الصفحة، ثم أرسل حدثًا تجريبيًا. إذا ظهر التنبيه مرة واحدة، فالسبب على الأرجح مرتبط بإعدادات المشهد أو بوجود عدة نسخ من المصدر. وإذا تكرر في تبويب منفصل بالفعل، فتحقق من كود الصفحة وآلية الاشتراك.
من المفيد تقسيم معالجة التبرع إلى عدة مراحل: استلام الحدث، والتحقق من الحدث، وإضافة التنبيه إلى قائمة الانتظار، والعرض. أخرِج مؤقتًا علامة عند كل مرحلة في السجل أو وحدة التحكم. إذا ظهر سجل الاستلام مرتين، فالمشكلة تقع قبل الطبقة المرئية. وإذا استُلم الحدث مرة واحدة لكن قائمة الانتظار تحتوي على عنصرين، فالخطأ في المعالج. وإذا احتوت قائمة الانتظار على عنصر واحد لكن الشاشة تعرض تنبيهين، فتحقق من دالة العرض وحاوية HTML.
للتشخيص، أضف إلى كل حدث معرّفه إن كان يُرسَل في بيانات التبرع. سجّل هذا المعرّف عند الاستلام وقبل العرض. المعرّف نفسه في استدعاءين يوضح أن حدثًا واحدًا عولج بشكل متكرر. أما المعرّفان المختلفان فيشيران إلى تسليمين يجب تحليلهما بشكل منفصل.
لا تتحقق من عدد التبويبات فقط. في OBS قد تظهر نسختان بعد نسخ المشهد أو إضافة مشهد مضمّن أو إضافة مصدر المتصفح نفسه بالعنوان ذاته مرة أخرى. أحيانًا يبقى أحد المصادر في طبقة منفصلة ويُضاف الثاني فوقه. يبدو هذا بصريًا كتنبيه مزدوج رغم أن الحدث وصل مرة واحدة.
إعادة الاشتراك بعد إعادة الاتصال
السبب الأكثر شيوعًا هو أن المعالج يُضاف عند كل اتصال لكنه لا يُزال عند قطع الاتصال. بشكل مبسط تبدو المشكلة هكذا: تشغّل الدالة socket.on مع معالج عرض التنبيه، ثم ينقطع الاتصال، فيتصل التطبيق مجددًا ويكرر socket.on. بعد ذلك يتسبب تبرع واحد وارد في استدعاء دالتين. ومع إعادة الاتصال التالية قد يزداد العدد أكثر.
يظهر الخطأ نفسه مع addEventListener العادي. إذا نُفّذت دالة التهيئة عدة مرات، يضيف المتصفح عدة مستمعين للحدث نفسه. والتحقق من علامة «تمت التهيئة بالفعل» لا يساعد دائمًا: عند التحديث الكامل للصفحة تُعاد تعيين المتغيرات، وعند إعادة الاتصال داخل الصفحة نفسها تبقى المشكلة قائمة.
يجب إنشاء الاشتراك مرة واحدة خلال دورة حياة الاتصال، وإزالة الاشتراك القديم صراحةً قبل الجديد. بالنسبة لمعالجات الأحداث يُستخدم removeEventListener مع المرجع نفسه للدالة الذي مُرِّر عند الاتصال. وبالنسبة للمكتبات التي تستخدم المقابس يلزم عادةً أسلوب off أو unsubscribe أو ما يشبهه لإلغاء الاشتراك.
قد يبدو المخطط الأدنى للمقبس هكذا: const onDonation = data => showAlert(data); socket.off('donation', onDonation); socket.on('donation', onDonation); function cleanup() { socket.off('donation', onDonation); window.removeEventListener('beforeunload', cleanup); socket.close(); } window.addEventListener('beforeunload', cleanup);
المهم هنا ليس المكتبة بعينها بل ترتيب الخطوات. يُخزَّن المعالج في متغير، لذلك يمكن إزالته بالمرجع نفسه. قبل الاشتراك الجديد يُزال القديم، وعند إغلاق الصفحة أو إيقاف المصدر يُنفَّذ cleanup. وإذا كان يُنشأ مقبس جديد عند كل تشغيل، فيجب أولًا إغلاق القديم ثم إنشاء الجديد فقط. وإلا فقد يستمر الاتصالان في استلام البيانات نفسها.
عند إعادة الاتصال أغلق أيضًا الاتصال القديم ونظّف المؤقتات المرتبطة به. وإلا فقد يستمر المقبس القديم في استلام البيانات بينما يعمل الجديد بالفعل. يحدث هذا كثيرًا خصوصًا إذا كان الكود يشغّل مؤقت إعادة اتصال جديد دون إلغاء المؤقت السابق.
ما يجب التحقق منه في OBS ومصدر المتصفح
إذا كانت النافذة المنفصلة تعرض التنبيه مرة واحدة، فانتقل إلى المشهد. أوقف المعاينة، واحذف الطبقات الزائدة مؤقتًا، واترك مصدر متصفح واحدًا. ثم تحقق من السلوك في المشهد المطلوب. هذا الاختبار أسرع من التحقق من جميع المشاهد والمرشحات في الوقت نفسه.
- ابحث عن مصدرين يحملان عنوان الصفحة نفسه.
- تحقق من نسخ المشاهد والمشاهد المضمّنة التي قد تحتوي على الطبقة نفسها.
- تأكد من أن التنبيه لا يُعرض في الوقت نفسه عبر مصدر المتصفح وعبر طبقة أخرى بالصفحة نفسها.
- بعد تغيير الإعدادات أعد تشغيل المصدر بالكامل، لا تكتفِ بتبديل المشهد.
أحيانًا يبقى في OBS تبويب قديم لمصدر المتصفح بعد تحديث عنوان URL أو المعلمات. إغلاق المصدر وإضافته من جديد يساعد على التحقق من الفرضية، لكنه لا يغني عن إصلاح الكود. إذا عادت المشكلة بعد كل تحديث، فابحث عن تسجيل متكرر للمعالج أو اتصال مزدوج.
ضع في الحسبان أيضًا تأخير قطع الاتصال. عند التحديث قد لا تُغلق الجلسة القديمة على الفور. إذا اعتبر الخادم أنها نشطة لبضع ثوانٍ، فقد يصل الحدث الوارد في هذه الفترة إلى جلستين. ويجب أن يحذف منطق الخادم السليم الاتصالات غير النشطة وألا يترك الاشتراك بعد إغلاق الصفحة.

الحماية من التسليم المتكرر لحدث واحد
حتى مع العمل الصحيح لمصدر المتصفح قد يُسلَّم الحدث الواحد مرة أخرى أحيانًا. هذا ممكن عند استعادة الاتصال أو إعادة إرسال الرسالة أو حدوث خلل بين استلام الحدث وتأكيد معالجته. لذلك يجب أن يكون معالج التنبيه مقاومًا للتكرار.
أفضل طريقة هي التحقق من المعرّف الفريد للتبرع. قبل إضافة الحدث إلى قائمة الانتظار احفظ معرّفه في مجموعة الأحداث المعالجة بالفعل. وإذا ظهر هذا المعرّف سابقًا، فيجب تخطي التكرار. وينبغي حفظ القائمة لمدة محدودة حتى لا تنمو بلا نهاية.
لا تستخدم لهذا الغرض المبلغ فقط أو اسم المرسل أو نص الرسالة. فقد يكون لتبرعين مختلفين البيانات نفسها. والتحقق بالوقت أيضًا غير موثوق: فقد يصل عدة تبرعات مختلفة في وقت متقارب. وإذا لم يكن هناك معرّف، يمكن مؤقتًا مقارنة مجموعة من الحقول والوقت، لكن هذا حل احتياطي ينطوي على خطر دمج حدثين بالخطأ.
يجب أن تكون الحماية من التكرار قبل عرض التنبيه لا داخل الحركة. وإلا فإن الاستدعاء الثاني سيضيف عنصرًا إلى الصفحة أو يشغّل الصوت أو يضع سجلًا آخر في قائمة الانتظار على أي حال. وتحكّم في قائمة الانتظار بشكل منفصل: يجب إضافة الحدث الواحد إليها مرة واحدة، وألا يشغّل الاستدعاء المتكرر قائمة انتظار ثانية مستقلة.
إذا كان الحدث يُنقل بين عدة تبويبات أو مكوّنات، فتحقق مما إذا كانت عدة جهات تستقبله تعالجه في الوقت نفسه. فقد تكون قناة رسائل مشتركة واحدة متصلة بعدة معالجات. في هذه الحالة يجب إما الإبقاء على مستهلك واحد أو تحديد المكوّن المسؤول عن عرض التنبيه صراحةً.
لماذا لا يساعد مسح ذاكرة التخزين المؤقت دائمًا
بعد تحديث مصدر المتصفح يُنصح غالبًا بمسح ذاكرة التخزين المؤقت. قد يصلح هذا الوضع إذا حُمّلت نسخة قديمة من السكربت، لكن ذاكرة التخزين المؤقت لا تزيل المعالجات الزائدة في صفحة تعمل بالفعل ولا تغلق النسخة الثانية من المصدر. وإذا تكرر التكرار بثبات بعد كل إعادة اتصال، فالسبب على الأرجح في منطق الاتصال أو في بنية المشهد.
تحقق مما إذا كانت النسخة الجديدة من الملفات تُحمَّل فعلًا. غيّر عنوان المورد مؤقتًا أو استخدم آلية التحديث المتاحة، ثم أعد تشغيل مصدر المتصفح. بعد ذلك نفّذ الاختبار مرة أخرى بنافذة واحدة ونسخة واحدة من المصدر. لا تُضف معلمات عشوائية إلى الرابط باستمرار: فقد ينشئ هذا العديد من نسخ ذاكرة التخزين المؤقت ويعقّد التشخيص.
إذا كانت هناك ذاكرة تخزين مؤقت وسيطة أو service worker، فقد يقدّم هو أيضًا سكربتًا قديمًا. في هذه الحالة قارن نسخة الملف المحمّل بالنسخة التي تتوقع رؤيتها. لكن حتى مع ملف قديم يجب إزالة سبب إعادة الاشتراك، وإلا فستظهر المشكلة مجددًا بعد التحديث التالي.
ما يجب التحقق منه في كود التنبيه
أولًا ابحث عن جميع المواضع التي تُستدعى فيها socket.on وaddEventListener ودوال الاتصال وتشغيل قائمة الانتظار. أحيانًا لا تكون المشكلة في معالج واحد، بل في أن وحدتين مختلفتين تستمعان إلى حدث donation بشكل مستقل وكل منهما تشغّل عرضها الخاص.
ثم تحقق من دورة حياة المكوّن إذا كان التنبيه يُعرض عبر إطار عمل. يوضع الاشتراك في تأثير أو كتلة مشابهة وتُعاد دالة التنظيف. لا يجوز إنشاء معالج جديد عند كل تحديث للحالة دون إزالة السابق. وفي JavaScript العادي من المهم تخزين مرجع للمقبس النشط والمعالج الحالي حتى يمكن إغلاقهما بشكل صحيح عند إيقاف الصفحة.
تحقق من مؤقتات إعادة الاتصال. لا يجوز تشغيل مؤقت جديد فوق القديم. وإلا فبعد عدة انقطاعات تُنشأ محاولات اتصال متوازية، ومعها اشتراكات إضافية. وكل مؤقت يحتاج إلى تنظيف عبر clearTimeout أو clearInterval إذا لم يعد لازمًا.
انظر بشكل منفصل إلى الكود الذي يعرض التنبيه. لا يجوز أن يضيف العنصر إلى قائمة الانتظار ويستدعي دالة العرض فورًا للكائن نفسه في الوقت ذاته. وتحقق أيضًا مما إذا كانت الحركة تُشغَّل مرة أخرى عند تغيّر حالة العنصر. وإذا كان السجل يظهر استلامًا واحدًا وسجلًا واحدًا في قائمة الانتظار بينما تعرض الشاشة إشعارين، فالبحث يجب أن يكون هنا تحديدًا.
قائمة تشخيص: ما يجب فعله بالترتيب
- افتح عنوان URL لمصدر المتصفح في تبويب منفصل وأرسل تبرعًا تجريبيًا واحدًا. سجّل ما إذا كان التكرار يظهر خارج OBS.
- اترك في المشهد نسخة واحدة فقط من المصدر. تحقق من نسخ المشاهد والمشاهد المضمّنة والطبقات التي قد تحتوي على العنوان نفسه.
- أضف سجلًا بمعرّف الحدث في مراحل الاستلام وإضافة قائمة الانتظار والعرض. بهذا سيظهر أين يزداد عدد الكائنات.
- ابحث عن جميع استدعاءات socket.on وaddEventListener. تحقق مما إذا كانت المعالجات القديمة تُزال عبر socket.off وremoveEventListener بالمرجع نفسه للدالة.
- تحقق من إعادة الاتصال: هل يُغلق المقبس القديم، وهل يُلغى المؤقت القديم، وهل يُنشأ اشتراك جديد فوق السابق.
- أضف تحققًا من المعرّف الفريد للتبرع قبل قائمة الانتظار، ثم أعد تشغيل المصدر بالكامل وكرر الاختبار بحدث واحد.
إذا كان التبويب المنفصل يستلم الحدث مرة واحدة بينما يعرض OBS تنبيهين، فابحث عن النسخة الثانية من المصدر أو عن تكرار في المشاهد. وإذا وصل الحدث مرتين في التبويب المنفصل بالفعل، فتحقق من الاشتراكات والاتصالات والتسليم من الخادم. وإذا سُجّل الاستلام وقائمة الانتظار مرة واحدة لكن الشاشة تعرض إشعارين، فالمشكلة في الطبقة المرئية.
Last Articles
ما الذي تغيّر في التصميم والوظائف قمنا بتحديث الموقع ليكون العمل عليه أسرع وأكثر راحة. التغييرات الرئيسية تتعلق بالواجهة والحساب الشخصي وإدارة الطلبا..
Good afternoon, I've collected all the news during this time.: 1. The main news is that prices for twitch viewers have been greatly reduced, while Tw..
1. استخدم كود الخصم "December2025" للحصول على خصم 15٪ لجميع مشاهدينا2. لقد خفضنا حتى 1 يناير الأسعار الأساسية لـ أداة التكوين الخاصة بنا وأرخص فئة للم..
خدمات نشل هي العمل بثبات ، لذلك نحن على استعداد للتعاون مع الفرق والبائعين, أصحاب الخدمة ، وأصحاب بوت ، وغيرها الكثير.يمكن مناقشة المصطلحات الفردي..
نحن لقد قمت بتحديث خدمات عارض نشل لدينا بالكامل ، وهم الآن العمل بثبات. نحن نستخدم فقط عناوين إب عالية الجودة للمشاهدين.يكمن الفارق الدقيق في الطل..
Hello everyone! Today, we are announcing a new feature—"Twitch Viewer Configurator". Now, you can customize any plan for your Twitch channel. Choo..
Greetings, I have compiled a guide for streamers, which will be very relevant at the moment. Now YouTube and twitch have disabled monetization from vi..
We have finally developed the APINow it will be more convenient for our partner sites to work with us.To update the maximum tariffs for YouTube, an up..
نظرًا للشعبية الكبيرة التي تتمتع بها خدمات الشراكة وبرامج الإحالة، فقد قمنا بإنشاء جدول تعاون. والجوهر بسيط للغاية: المزيد من الجمهور المباشر - المزيد..
خدماتنا للبث المباشر

Shopee
خدماتنا لصانعي المحتوى









