পাঠ ৪৫ · ৫৭-এর মধ্যে · মডিউল ১০
Home / Courses / Mobile App Development / পুশ নোটিফিকেশন

পুশ নোটিফিকেশন

Push notifications
৯ মিনিট পড়া মধ্যম · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

এই পাঠে যা শিখবেন

  • একটি সত্যিকারের Broker pub-sub ক্লাস — টপিক-ভিত্তিক সাবস্ক্রিপশন ও সরাসরি ডেলিভারি
  • কেন নোটিফিকেশন শুধু সঠিক টপিকের সাবস্ক্রাইবারের কাছেই পৌঁছাতে হবে, বাকিদের কাছে নয়
  • একটি self-contained নেভিগেশন স্ট্যাক (push/current) এই কোর্সেরই ভাবনায়
  • Broker-এর ডেলিভারিকে নেভিগেশন স্ট্যাকের সাথে জুড়ে একটি সম্পূর্ণ "নোটিফিকেশন ট্যাপ" ফ্লো end-to-end চালানো

১ · Broker — টপিক-ভিত্তিক pub-sub

একটি পুশ নোটিফিকেশন সিস্টেমে সাধারণত একাধিক ধরনের ঘটনা থাকে (নতুন চ্যাট মেসেজ, ফ্রেন্ড রিকোয়েস্ট, প্রমো অফার), এবং অ্যাপের ভিন্ন ভিন্ন অংশ শুধু নির্দিষ্ট ধরনের ঘটনায় আগ্রহী। এই সমস্যার সমাধান করে BrokerBroker (Pub-Sub)একটি কেন্দ্রীয় অবজেক্ট যেখানে বিভিন্ন অংশ নির্দিষ্ট "টপিক"-এ সাবস্ক্রাইব করে রাখে, এবং কোনো ঘটনা ঘটলে সেই টপিকে "publish" করা মাত্র শুধুমাত্র সেই টপিকের সাবস্ক্রাইবাররাই খবর পায় — বাকিরা কিছুই জানে না। প্যাটার্ন — subscribe(topic, callback) দিয়ে আগ্রহ নিবন্ধন করা হয়, আর publish(topic, payload) শুধু সেই টপিকের callback-গুলোকে কল করে।

Python
# একটি সত্যিকারের Broker -- টপিক-ভিত্তিক pub-sub, সরাসরি ডেলিভারি

class Broker:
    def __init__(self):
        self._subscribers = {}  # topic (str) -> callback-দের লিস্ট

    def subscribe(self, topic, callback):
        self._subscribers.setdefault(topic, []).append(callback)
        print(f"  [subscribe] topic={topic!r} -> {callback.__name__}")

    def publish(self, topic, payload):
        handlers = self._subscribers.get(topic, [])
        print(f"  [publish]   topic={topic!r} payload={payload} -> {len(handlers)}টি সাবস্ক্রাইবার")
        for callback in handlers:
            callback(payload)

def log_chat_analytics(payload):
    print(f"    [analytics] চ্যাট নোটিফিকেশন লগ হলো: id={payload['id']}")

broker = Broker()
broker.subscribe("chat_message", log_chat_analytics)

print("\n== একটি chat_message পাবলিশ করা হলো ==")
broker.publish("chat_message", {"id": 482, "preview": "তুমি কি কাল আসবে?"})

print("\n== একটি টপিক পাবলিশ করা হলো যার কোনো সাবস্ক্রাইবার নেই ==")
broker.publish("promo_offer", {"id": 1})

    
লক্ষ্য করুন promo_offer পাবলিশ করলে 0টি সাবস্ক্রাইবার প্রিন্ট হয় এবং কোনো callback কল হয় না — কারণ self._subscribers.get(topic, []) একটি খালি লিস্ট রিটার্ন করে যখন সেই টপিকে কেউ সাবস্ক্রাইব করেনি। Broker কখনো ভুল টপিকের সাবস্ক্রাইবারকে ডেকে ফেলে না — ডেলিভারি সবসময় টপিক-নির্দিষ্ট।

২ · নোটিফিকেশন ট্যাপ → নেভিগেশন স্ট্যাকে push — end-to-end

শুধু ডেলিভারি যথেষ্ট নয় — একটি real পুশ নোটিফিকেশন সিস্টেমে ইউজার নোটিফিকেশনে ট্যাপ করলে অ্যাপকে সঠিক স্ক্রিনে নিয়ে যেতে হয়। নিচের কোডে একটি self-contained নেভিগেশন স্ট্যাক তৈরি করে Broker-এর ডেলিভারিকে সরাসরি সেই স্ট্যাকের push()-এর সাথে জুড়ে দেওয়া হয়েছে — এটিই "নোটিফিকেশন ট্যাপ" ফ্লো।

Python
# একটি self-contained নেভিগেশন স্ট্যাক

class NavigationStack:
    def __init__(self, root):
        self._stack = [root]

    def push(self, screen):
        self._stack.append(screen)

    def current(self):
        return self._stack[-1]

    def __repr__(self):
        return " > ".join(self._stack)

nav_stack = NavigationStack("Home")

# Broker-কে নেভিগেশন স্ট্যাকের সাথে জুড়ে দেওয়া হচ্ছে -- ডেলিভারি -> push()
def on_chat_notification_tap(payload):
    """নোটিফিকেশনে ট্যাপ করলে -- payload অনুযায়ী নির্দিষ্ট স্ক্রিন নেভিগেশন স্ট্যাকে push হয়"""
    target_screen = f"ChatThread(id={payload['id']})"
    nav_stack.push(target_screen)
    print(f"    [handler:chat_message] push('{target_screen}')")

def on_friend_request_tap(payload):
    target_screen = f"FriendRequest(id={payload['id']})"
    nav_stack.push(target_screen)
    print(f"    [handler:friend_request] push('{target_screen}')")

nav_broker = Broker()
nav_broker.subscribe("chat_message", on_chat_notification_tap)
nav_broker.subscribe("friend_request", on_friend_request_tap)

print(f"\nট্যাপের আগে স্ট্যাক: {nav_stack}")

# একটি concrete নোটিফিকেশন পেলোড -- ইউজার এই চ্যাট নোটিফিকেশনে ট্যাপ করলো
chat_payload = {"id": 482, "preview": "তুমি কি কাল আসবে?"}
nav_broker.publish("chat_message", chat_payload)

print(f"\nট্যাপের পরে স্ট্যাক: {nav_stack}")
print(f"বর্তমান স্ক্রিন: {nav_stack.current()}")

    
ট্যাপের আগে স্ট্যাক শুধু Home। nav_broker.publish("chat_message", chat_payload) কল হওয়া মাত্র শুধু on_chat_notification_tap কল হয় (কারণ পেলোড "chat_message" টপিকে পাবলিশ হয়েছে, "friend_request"-এ নয়) — যা nav_stack.push("ChatThread(id=482)") কল করে। ফলে ট্যাপের পরে স্ট্যাক হয় Home > ChatThread(id=482), আর current() রিটার্ন করে "ChatThread(id=482)" — এটিই প্রমাণ করে Broker-এর ডেলিভারি সত্যিই নেভিগেশন স্ট্যাক বদলে দিয়েছে, শুধু প্রিন্ট নয়।
মূল কথা · Key takeaway

পুশ নোটিফিকেশন সিস্টেমের দুটো আলাদা কাজ — ডেলিভারি (Broker-এর pub-sub) এবং নেভিগেশন (স্ট্যাকে push) — আলাদা ক্লাসে থাকলেও একটি concrete হ্যান্ডলার ফাংশন দিয়ে সরাসরি জোড়া লাগানো যায়। এই "wiring" প্যাটার্নটিই L57-এর ক্যাপস্টোনে একাধিক CORE প্যাটার্ন জোড়া লাগানোর সময় আবার দেখা যাবে।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।

প্র ০১ দ্বিতীয় কোড সেলে nav_broker.publish("chat_message", chat_payload) কল করা হলে on_friend_request_tap কেন কল হয় না?

কারণ on_friend_request_tap সাবস্ক্রাইব করা হয়েছে "friend_request" টপিকে, "chat_message"-এ নয়। publish মেথড শুধু self._subscribers[topic]-এ থাকা callback-গুলোকেই কল করে — Broker-এর টপিক-ভিত্তিক রাউটিং নিশ্চিত করে যে অপ্রাসঙ্গিক হ্যান্ডলার কখনো ভুল ঘটনায় সাড়া দেয় না।

প্র ০২ যদি একই "chat_message" টপিকে দুটো ভিন্ন callback সাবস্ক্রাইব করা থাকতো (যেমন একটি নেভিগেশনের জন্য, একটি অ্যানালিটিক্স লগের জন্য), একটি publish কল কতবার callback ইনভোক করতো?

দুইবার — একটি করেই। publish-এর for callback in handlers: লুপ সেই টপিকের প্রতিটি সাবস্ক্রাইব করা callback-কে একবার করে, ক্রমানুসারে কল করে। এটিই দেখায় কেন একই ঘটনায় একাধিক, সম্পূর্ণ স্বাধীন প্রতিক্রিয়া (নেভিগেশন + লগিং) একসাথে চালানো সম্ভব, একে অপরের কোড না ছুঁয়েই।

প্র ০৩ L40-এ শেখা "OS পুশ বনাম in-app WebSocket" পার্থক্যের সাথে এই পাঠের Broker-এর সম্পর্ক কী?

L40 কভার করেছে ডেলিভারি অ্যাপের লাইফসাইকেল স্টেটের ওপর নির্ভর করে কীভাবে সফল বা ব্যর্থ হয় (OS পুশ killed অবস্থাতেও পৌঁছায়, WebSocket পৌঁছায় না)। এই পাঠের Broker ধরে নেয় ডেলিভারি ইতিমধ্যে হয়ে গেছে (অ্যাপ এখন খোলা, ইউজার নোটিফিকেশনে ট্যাপ করেছে) এবং ফোকাস করে তারপর কী হয় — অ্যাপের ভেতরে সঠিক হ্যান্ডলার খুঁজে বের করা ও সঠিক স্ক্রিনে নেভিগেট করা। দুটো ভিন্ন স্তরের সমস্যা, একে অপরের পরিপূরক।

অনুশীলন

  1. চিন্তা করুন: একটি ই-কমার্স অ্যাপে "অর্ডার ডেলিভার্ড" নোটিফিকেশনে ট্যাপ করলে অর্ডার-ডিটেইলস স্ক্রিনে যাওয়া উচিত, কিন্তু ইউজার যদি ইতিমধ্যে সেই একই অর্ডার-ডিটেইলস স্ক্রিনে থাকে, তাহলে কি আবার একই স্ক্রিন push করা ঠিক হবে, নাকি অন্য কিছু করা উচিত?

    সাধারণত একই স্ক্রিন দ্বিতীয়বার push না করাই ভালো UX — এতে ব্যাক বাটনে দুইবার চাপতে হয়। একটি ভালো ডিজাইনড হ্যান্ডলার প্রথমে nav_stack.current() চেক করে দেখতে পারতো লক্ষ্য স্ক্রিন ইতিমধ্যে বর্তমান কিনা, এবং হলে push এড়িয়ে যেতে পারতো — এটিই L27 (নেভিগেশন স্টেট) ও L24 (স্ট্যাক বেসিক)-এর ধারণাগুলো এখানে প্রয়োগের একটি বাস্তব উদাহরণ।

  2. পরীক্ষা করুন: দ্বিতীয় কোড সেলে chat_payload-এর পরে আরেকটি পাবলিশ যোগ করুন — nav_broker.publish("friend_request", {"id": 17}) — এবং দেখুন এবার স্ট্যাক ও current() কী দেখায়।

    এই কল on_friend_request_tap-কে ইনভোক করবে, যা nav_stack.push("FriendRequest(id=17)") কল করবে। ফলে স্ট্যাক হবে Home > ChatThread(id=482) > FriendRequest(id=17), আর current() রিটার্ন করবে "FriendRequest(id=17)" — দেখাচ্ছে একাধিক নোটিফিকেশন ট্যাপ ক্রমান্বয়ে স্ট্যাকে জমা হতে থাকে, ঠিক যেমন real নেভিগেশনে হয়।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

  • কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ অ্যাপ লাইফসাইকেল, মোবাইল UI/UX, MVVM/MVI আর্কিটেকচার, নেটিভ বনাম ক্রস-প্ল্যাটফর্ম, নেভিগেশন, স্টেট ম্যানেজমেন্ট, লোকাল স্টোরেজ, ডিভাইস ফিচার ও ডিপ্লয়মেন্ট — বাকি পাঠগুলো শীঘ্রই যুক্ত হবে।
  • Full-Stack Web Frameworks কোর্স সহোদর কোর্স ওয়েবে Push API/Service Worker দিয়ে সীমিত ব্রাউজার নোটিফিকেশন মেলে, শুধু ট্যাব/ব্রাউজার খোলা বা ইনস্টল করা অবস্থায় — মোবাইলে OS-লেভেল পুশ সার্ভিস অ্যাপ সম্পূর্ণ বন্ধ থাকলেও ডেলিভারি নিশ্চিত করে।
  • সব Courses দেখুন ABCL TECH C, C++, Python, Java, JavaScript, DSA, DBMS, Discrete Mathematics, System Design, Cybersecurity, Cloud Computing & DevOps, Computer Networks, Operating Systems, Computer Architecture, Programming Languages & Compiler Design, Software Engineering & Git, Theory of Computation, Engineering Economics, Full-Stack Web Frameworks ও Mobile App Development — সব এক জায়গায়।
আগের পাঠ
সেন্সর ও বায়োমেট্রিক