چرا یک دونیت پس از بهروزرسانی منبع مرورگر دو هشدار ایجاد میکند
چرا یک دونیت دو هشدار ایجاد میکند
پس از بهروزرسانی منبع مرورگر، صفحه از نو راهاندازی میشود. اسکریپت دوباره به سرور متصل میشود، در رویدادها مشترک میشود و برای نمایش اعلانها پردازشگر ایجاد میکند. اگر پردازشگر قدیمی حذف نشده باشد یا دو اتصال همزمان فعال باشند، یک رویداد دونیت چند بار پردازش میشود.
خود بهروزرسانی لزوماً علت خرابی نیست. اغلب فقط خطای منطق اتصال را آشکار میکند. برای مثال، تابع مقداردهی اولیه ممکن است هنگام بارگذاری صفحه اجرا شود، سپس هنگام بازیابی اتصال و یک بار دیگر پس از دریافت پیام سرویس. هر اجرا یک اشتراک جدید برای رویداد 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 و منبع مرورگر چه چیزی را بررسی کنیم
اگر پنجره جداگانه هشدار را یک بار نشان میدهد، به سراغ صحنه بروید. پیشنمایش را متوقف کنید، لایههای اضافی را موقتاً حذف کنید و یک منبع مرورگر باقی بگذارید. سپس رفتار را در صحنه موردنظر بررسی کنید. این آزمایش از بررسی همزمان همه صحنهها و فیلترها سریعتر است.
- به دنبال دو منبع با یک آدرس صفحه یکسان بگردید.
- کپیهای صحنه و صحنههای تودرتو را که ممکن است همان اورلی در آنها باشد بررسی کنید.
- مطمئن شوید که هشدار همزمان توسط منبع مرورگر و لایهای دیگر با همان صفحه نمایش داده نمیشود.
- پس از تغییر تنظیمات، منبع را بهطور کامل دوباره راهاندازی کنید، نه اینکه فقط صحنه را عوض کنید.
گاهی پس از بهروزرسانی URL یا پارامترها، تب قدیمی منبع مرورگر در OBS باقی میماند. بستن و افزودن مجدد منبع به بررسی این فرضیه کمک میکند، اما جای اصلاح کد را نمیگیرد. اگر پس از هر بهروزرسانی مشکل برمیگردد، به دنبال ثبت مجدد پردازشگر یا اتصال دوتایی بگردید.
تأخیر قطع اتصال را هم در نظر بگیرید. هنگام بهروزرسانی، نشست قدیمی ممکن است بلافاصله بسته نشود. اگر سرور چند ثانیه آن را فعال بداند، رویدادی که در این فاصله میرسد ممکن است به دو نشست برسد. منطق صحیح سرور باید اتصالهای غیرفعال را حذف کند و پس از بستن صفحه اشتراکی باقی نگذارد.

محافظت در برابر تحویل مجدد یک رویداد
حتی با عملکرد صحیح منبع مرورگر، گاهی یک رویداد ممکن است دوباره تحویل داده شود. این امر در بازیابی اتصال، ارسال مجدد پیام یا خطا بین دریافت رویداد و تأیید پردازش آن ممکن است. بنابراین پردازشگر هشدار باید در برابر تکرار مقاوم باشد.
بهترین روش بررسی شناسه یکتای دونیت است. پیش از قرار دادن رویداد در صف، شناسه آن را در مجموعه رویدادهای پردازششده ذخیره کنید. اگر چنین شناسهای قبلاً دیده شده باشد، تکرار باید رد شود. فهرست را باید مدت محدودی نگه داشت تا بینهایت رشد نکند.
برای این کار فقط از مبلغ، نام فرستنده یا متن پیام استفاده نکنید. دو دونیت متفاوت ممکن است داده یکسانی داشته باشند. بررسی بر اساس زمان هم قابل اعتماد نیست: چند دونیت متفاوت ممکن است تقریباً همزمان برسند. اگر شناسه وجود ندارد، میتوان بهطور موقت ترکیبی از فیلدها و زمان را مقایسه کرد، اما این روش جایگزین با خطر ادغام اشتباه دو رویداد است.
محافظت در برابر تکرار باید پیش از نمایش هشدار باشد، نه داخل انیمیشن. در غیر این صورت فراخوانی دوم همچنان عنصری به صفحه اضافه میکند، صدا پخش میکند یا یک رکورد دیگر در صف قرار میدهد. صف را جداگانه کنترل کنید: یک رویداد باید یک بار به آن اضافه شود و فراخوانی مجدد نباید صف مستقل دومی را اجرا کند.
اگر رویداد بین چند تب یا مؤلفه منتقل میشود، بررسی کنید که آیا چند دریافتکننده آن را همزمان پردازش نمیکنند. یک کانال پیام مشترک ممکن است به چند پردازشگر متصل باشد. در چنین حالتی باید یا یک مصرفکننده باقی بگذارید یا صریحاً مشخص کنید کدام مؤلفه مسئول نمایش هشدار است.
چرا پاک کردن کش همیشه کمک نمیکند
پس از بهروزرسانی منبع مرورگر اغلب توصیه میشود کش پاک شود. این ممکن است وضعیت را اصلاح کند اگر نسخه قدیمی اسکریپت بارگذاری شده باشد، اما کش پردازشگرهای اضافی را در صفحهای که از قبل در حال اجراست حذف نمیکند و نسخه دوم منبع را نمیبندد. اگر تکرار پس از هر اتصال دوباره بهطور پایدار تکرار شود، علت تقریباً قطعاً در منطق اتصال یا ساختار صحنه است.
بررسی کنید که آیا واقعاً نسخه جدید فایلها بارگذاری میشود. آدرس منبع را موقتاً تغییر دهید یا از مکانیزم بهروزرسانی پیشبینیشده استفاده کنید، سپس منبع مرورگر را دوباره راهاندازی کنید. پس از آن دوباره آزمایش را با یک پنجره و یک نمونه از منبع انجام دهید. پارامترهای تصادفی را بهطور مداوم به لینک اضافه نکنید: این کار ممکن است variants زیادی از کش ایجاد کند و عیبیابی را پیچیدهتر کند.
اگر از کش واسط یا 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 ژانویه قیمتهای پایه برای ابزار پیکربندی و مقرونبهصرفهت..
خدمات Twitch با ثبات کار ميکنيم ، پس آماده ايم با گروه ها و فروشنده ها همکاري کنيم, صاحبان خدمات ، صاحبان ربات ها و بسیاری دیگر.اصطلاحات فردی را م..
ما خدمات twitch viewer ما را به طور کامل به روز کرده اند و اکنون کار پایدار. ما فقط از آدرس های ip با کیفیت بالا برای بینندگان استفاده می کنیم.این..
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
خدمات ما برای تولیدکنندگان محتوا









