شکافی که زنگ اعلان درونبرنامهای نمیتواند ببندد
زنگ اعلان ویکیافگو خوب کار میکند — تا وقتی کسی تب را میبندد. یک تسک ساعت ۴ بعدازظهر به او تخصیص داده میشود و صبح روز بعد میفهمد، چون وقتی مرورگر باز نبود چیزی فایر نشد. این باگ زنگ نیست؛ سقف کاری است که یک عنصر UI درونبرنامهای میتواند انجام دهد. بستن این شکاف چیزی لازم دارد که بتواند حتی وقتی اپتان در مرورگر اجرا نیست، به مرورگر برسد.
Web Push، در یک جمله
خودِ مرورگر — نه مستقیماً سرور ویکیافگو — یک اتصال ایستا با یک سرویس پوش (سرویس کروم، فایرفاکس، هرکدام که تأمینکنندهی مرورگر کاربر اجرا میکند) نگه میدارد. بکاند ویکیافگو یک بار رمزنگاریشده به آن سرویس پوش میفرستد، خطاب به یک اشتراک مشخص؛ مرورگر service worker را بیدار میکند تا اعلان را نشان دهد، حتی با بستهبودن هر تب ویکیافگو. همان سازوکاری است (RFC 8291) که به هر وبسایتی — نه فقط اپهای نصبشده — اجازه میدهد بعد از گرفتن اجازه، برایتان اعلان پوش بفرستد.
چرا این به هیچ App Store یا تنظیم FCM نیاز ندارد
// Web Push requires a secure context (HTTPS or localhost) on the client, so in
// a plain-http deployment the browser never produces a subscription and this
// domain simply has nothing to send — it degrades cleanly.
آن کامنت کل مدل اعتماد در یک خط است. هیچ اپ موبایل جدایی برای نصب نیست، هیچ پروژهی Firebase برای تنظیم نیست، هیچ گواهی APNs برای تمدید نیست. مرورگر خودش بهمحض اینکه کاربر موافقت کند اشتراک را میسازد؛ ویکیافگو فقط یک جفت کلید عمومی/خصوصیِ VAPID لازم دارد (خود-معرف، تا سرویسهای پوش بدانند کدام سرور اجازه دارد برای یک اشتراک مشخص بفرستد) و یک کتابخانه که پروتکل Web Push را میفهمد.
چهچیزی ذخیره میشود، و چهچیزی از پایگاهداده بیرون میماند
type Subscription struct {
UserID uint
Endpoint string
P256dh string `json:"-"`
Auth string `json:"-"`
CreatedAt time.Time
}
P256dh و Auth کلیدهای رمزنگاریای هستند که مرورگر برای همین اشتراک مشخص ساخته — ویکیافگو برای رمزنگاریِ باری که سرویس پوش نمیتواند بخواند به آنها نیاز دارد، اما با json:"-" علامتگذاری شدهاند تا هرگز در هیچ پاسخ APIای برنگردند. نقطهپایانی برای هر نصبِ مرورگر یکتاست؛ اشتراکمجددشدن روی همان دستگاه بهجای تکرارشدن جایگزین میشود.
چطور یک اعلان واقعاً به آنجا میرسد
هیچچیزی دربارهی پوش به یک مسیر کد جدا در منطق اعلانرسانی ویکیافگو نیاز نداشت — به همان یک جایی وصل میشود که هر اعلان درونبرنامهای از قبل از آن عبور میکند: هروقت خطلولهی موجود برای یک کاربر اعلانی صادر میکند، این هم چک میکند آیا آن کاربر اشتراک پوش زندهای دارد و همان رویداد را برایش هم پخش میکند. تخصیص یک تسک، یک منشن، یادآوریِ سررسید — یک محرک، دو مسیر تحویل، زنگ درونبرنامهای و پوش مرورگر، همیشه همگام چون همان رویداد مبدأ را به اشتراک میگذارند.
روشنکردنش
۱. اجازهی مرورگر را بدهید. در Settings → Notifications، فعالکردن پوش پرامپت اجازهی بومیِ مرورگر را فعال میکند. ردکردنش یک حالت خطا نیست — اپ دقیقاً مثل قبل کار میکند، فقط بدون تحویل روی تبِ بسته.
۲. یک اشتراک برای هر مرورگر، نه هر حساب. ورود به همان حساب ویکیافگو در یک موبایل و یک لپتاپ دو اشتراک میسازد؛ هر دو اعلان را میگیرند. از دستگاهی که دیگر استفاده نمیکنید خارج شوید، وگرنه نقطهپایانی همچنان برای حسابی که فعالانه چک نمیکنید پوش دریافت میکند.
۳. چیزی برای نصب نیست. بدون اپ نیتیو، بدون دانلود جدا — این قابلیتِ خودِ مرورگر است، از قبل در هر مرورگر مدرنی حاضر.
اشتباهات رایج
تستکردن روی HTTP ساده و نتیجهگیری اینکه پوش خراب است. نیست — مرورگر عمداً از ساختن اشتراک بیرون از یک بستر امن سرباز میزند. localhost برای توسعهی محلی استثناست؛ هر مبدأ HTTP سادهی دیگری بیصدا هیچچیز نمیگیرد.
فرضکردن اینکه یک پرامپتِ ردشده را میشود بیصدا دوباره امتحان کرد. مرورگرها یک رد را به خاطر میسپارند و خودکار دوباره پرامپت نمیدهند؛ کاربر باید اعلان را از تنظیمات مرورگر خودش برای سایت دوباره فعال کند.
اشتباهگرفتنش با اعلانهای ایمیلی. مسیرهای تحویل مستقلیاند که جدا تنظیم میشوند — ایمیل با زمانبندی خودش به یک صندوق ورودی میرسد؛ پوش در چند ثانیه به دستگاه میرسد، تا وقتی قفل باز و آنلاین است.
سؤالات متداول
آیا در مرورگرهای موبایل کار میکند؟ بله، در مرورگرهایی که Push API را پیادهسازی کردهاند — کروم و فایرفاکس موبایل پشتیبانی میکنند؛ بعضی مرورگرهای موبایل برای پوشِ پسزمینه وقتی خودِ پردازهی مرورگر کاملاً بسته است پشتیبانی جزئی یا هیچی دارند.
میتوانم دسترسی پوش یک دستگاه را از دستگاه دیگری لغو کنم؟ هنوز بهعنوان یک اقدام خودسرویس از اپ نه؛ اشتراک بهمحض لغوشدن اجازهی خودِ مرورگر یا کهنهشدن نقطهپایانی خودش پاک میشود.
آیا self-host کردن ویکیافگو نیاز به اجرای زیرساخت پوش خودم دارد؟ نه — شما جفتکلید VAPID خودتان را میسازید، اما خودِ سرویس پوش (کروم، فایرفاکس) زیرساخت تأمینکنندهی مرورگر است، نه چیزی که شما اجرایش کنید.