জাভাস্ক্রিপ্টে অফলাইন ক্ষমতা সক্রিয় করা হচ্ছে

আপনার অ্যাপের নেটওয়ার্ক সংযোগ সাময়িকভাবে বিচ্ছিন্ন হয়ে গেলেও Firebase অ্যাপ্লিকেশনগুলি কাজ করে। আমরা উপস্থিতি পর্যবেক্ষণ এবং স্থানীয় অবস্থাকে সার্ভারের অবস্থার সাথে সিঙ্ক্রোনাইজ করার জন্য বেশ কয়েকটি সরঞ্জাম সরবরাহ করি, যা এই নথিতে উপস্থাপন করা হয়েছে।

উপস্থিতি পরিচালনা

রিয়েলটাইম অ্যাপ্লিকেশনগুলিতে ক্লায়েন্ট কখন সংযোগ স্থাপন করে এবং সংযোগ বিচ্ছিন্ন করে তা সনাক্ত করা প্রায়শই কার্যকর। উদাহরণস্বরূপ, আপনি কোনও ব্যবহারকারীর ক্লায়েন্ট সংযোগ বিচ্ছিন্ন হয়ে গেলে তাকে 'অফলাইন' হিসাবে চিহ্নিত করতে পারেন।

ফায়ারবেস ডেটাবেস ক্লায়েন্টরা সহজ প্রিমিটিভ প্রদান করে যা আপনি যখন কোনও ক্লায়েন্ট ফায়ারবেস ডেটাবেস সার্ভার থেকে সংযোগ বিচ্ছিন্ন করে তখন ডাটাবেসে লেখার জন্য ব্যবহার করতে পারেন। ক্লায়েন্ট পরিষ্কারভাবে সংযোগ বিচ্ছিন্ন করুক বা না করুক, এই আপডেটগুলি ঘটে, তাই কোনও সংযোগ বিচ্ছিন্ন হয়ে গেলে বা ক্লায়েন্ট ক্র্যাশ করলেও আপনি ডেটা পরিষ্কার করার জন্য তাদের উপর নির্ভর করতে পারেন। সংযোগ বিচ্ছিন্ন হওয়ার পরে সেট করা, আপডেট করা এবং অপসারণ সহ সমস্ত লেখার ক্রিয়াকলাপ সম্পাদন করা যেতে পারে।

onDisconnect প্রিমিটিভ ব্যবহার করে সংযোগ বিচ্ছিন্ন করার সময় ডেটা লেখার একটি সহজ উদাহরণ এখানে দেওয়া হল:

Web

import { getDatabase, ref, onDisconnect } from "firebase/database";

const db = getDatabase();
const presenceRef = ref(db, "disconnectmessage");
// Write a string when this client loses connection
onDisconnect(presenceRef).set("I disconnected!");

Web

var presenceRef = firebase.database().ref("disconnectmessage");
// Write a string when this client loses connection
presenceRef.onDisconnect().set("I disconnected!");

অনডিসকানেক্ট কীভাবে কাজ করে

যখন আপনি একটি onDisconnect() অপারেশন স্থাপন করেন, তখন অপারেশনটি Firebase Realtime Database সার্ভারে থাকে। ব্যবহারকারী অনুরোধ করা লেখার ইভেন্টটি সম্পাদন করতে পারছেন কিনা তা নিশ্চিত করার জন্য সার্ভার নিরাপত্তা পরীক্ষা করে এবং যদি এটি অবৈধ হয় তবে আপনার অ্যাপটিকে অবহিত করে। সার্ভার তারপর সংযোগটি পর্যবেক্ষণ করে। যদি কোনও সময়ে সংযোগের সময়সীমা শেষ হয়ে যায়, অথবা Realtime Database ক্লায়েন্ট দ্বারা সক্রিয়ভাবে বন্ধ করা হয়, তাহলে সার্ভার দ্বিতীয়বার নিরাপত্তা পরীক্ষা করে (অপারেশনটি এখনও বৈধ কিনা তা নিশ্চিত করার জন্য) এবং তারপর ইভেন্টটি চালু করে।

আপনার অ্যাপটি onDisconnect সঠিকভাবে সংযুক্ত হয়েছে কিনা তা নিশ্চিত করতে write অপারেশনে কলব্যাক ব্যবহার করতে পারে:

Web

onDisconnect(presenceRef).remove().catch((err) => {
  if (err) {
    console.error("could not establish onDisconnect event", err);
  }
});

Web

presenceRef.onDisconnect().remove((err) => {
  if (err) {
    console.error("could not establish onDisconnect event", err);
  }
});

একটি onDisconnect ইভেন্ট .cancel() কল করেও বাতিল করা যেতে পারে:

Web

const onDisconnectRef = onDisconnect(presenceRef);
onDisconnectRef.set("I disconnected");
// some time later when we change our minds
onDisconnectRef.cancel();

Web

var onDisconnectRef = presenceRef.onDisconnect();
onDisconnectRef.set("I disconnected");
// some time later when we change our minds
onDisconnectRef.cancel();

সংযোগের অবস্থা সনাক্ত করা হচ্ছে

অনেক উপস্থিতি-সম্পর্কিত বৈশিষ্ট্যের জন্য, আপনার অ্যাপটি কখন অনলাইন বা অফলাইনে আছে তা জানা আপনার জন্য কার্যকর। Firebase Realtime Database /.info/connected এ একটি বিশেষ অবস্থান প্রদান করে যা Firebase Realtime Database ক্লায়েন্টের সংযোগ অবস্থা পরিবর্তনের সাথে সাথে প্রতিবার আপডেট করা হয়। এখানে একটি উদাহরণ দেওয়া হল:

Web

import { getDatabase, ref, onValue } from "firebase/database";

const db = getDatabase();
const connectedRef = ref(db, ".info/connected");
onValue(connectedRef, (snap) => {
  if (snap.val() === true) {
    console.log("connected");
  } else {
    console.log("not connected");
  }
});

Web

var connectedRef = firebase.database().ref(".info/connected");
connectedRef.on("value", (snap) => {
  if (snap.val() === true) {
    console.log("connected");
  } else {
    console.log("not connected");
  }
});

/.info/connected হল একটি বুলিয়ান মান যা Realtime Database ক্লায়েন্টদের মধ্যে সিঙ্ক্রোনাইজ করা হয় না কারণ মানটি ক্লায়েন্টের অবস্থার উপর নির্ভর করে। অন্য কথায়, যদি একটি ক্লায়েন্ট /.info/connected মিথ্যা হিসেবে পড়ে, তাহলে এটি কোনও গ্যারান্টি দেয় না যে একটি পৃথক ক্লায়েন্টও মিথ্যা পড়বে।

বিলম্ব সামলানো

সার্ভার টাইমস্ট্যাম্প

Firebase Realtime Database সার্ভারগুলি সার্ভারে তৈরি টাইমস্ট্যাম্পগুলিকে ডেটা হিসাবে সন্নিবেশ করার জন্য একটি প্রক্রিয়া প্রদান করে। এই বৈশিষ্ট্যটি, onDisconnect এর সাথে মিলিত হয়ে, একটি Realtime Database ক্লায়েন্ট সংযোগ বিচ্ছিন্ন হওয়ার সময় নির্ভরযোগ্যভাবে নোট করার একটি সহজ উপায় প্রদান করে:

Web

import { getDatabase, ref, onDisconnect, serverTimestamp } from "firebase/database";

const db = getDatabase();
const userLastOnlineRef = ref(db, "users/joe/lastOnline");
onDisconnect(userLastOnlineRef).set(serverTimestamp());

Web

var userLastOnlineRef = firebase.database().ref("users/joe/lastOnline");
userLastOnlineRef.onDisconnect().set(firebase.database.ServerValue.TIMESTAMP);

ঘড়ির স্কিউ

যদিও firebase.database.ServerValue.TIMESTAMP অনেক বেশি নির্ভুল এবং বেশিরভাগ পঠন/লেখার ক্রিয়াকলাপের জন্য পছন্দনীয়, তবুও মাঝে মাঝে Firebase Realtime Database এর সার্ভারের তুলনায় ক্লায়েন্টের ঘড়ির স্কিউ অনুমান করা কার্যকর হতে পারে। আপনি /.info/serverTimeOffset অবস্থানে একটি কলব্যাক সংযুক্ত করতে পারেন যাতে Firebase Realtime Database ক্লায়েন্টরা সার্ভারের সময় অনুমান করার জন্য স্থানীয় রিপোর্ট করা সময়ের (যুগের সময় মিলিসেকেন্ডে) যোগ করে যে মান মিলিসেকেন্ডে পেতে পারে। মনে রাখবেন যে এই অফসেটের নির্ভুলতা নেটওয়ার্কিং ল্যাটেন্সি দ্বারা প্রভাবিত হতে পারে এবং তাই এটি প্রাথমিকভাবে ঘড়ির সময়ের মধ্যে বড় (> 1 সেকেন্ড) অসঙ্গতি আবিষ্কারের জন্য কার্যকর।

Web

import { getDatabase, ref, onValue } from "firebase/database";

const db = getDatabase();
const offsetRef = ref(db, ".info/serverTimeOffset");
onValue(offsetRef, (snap) => {
  const offset = snap.val();
  const estimatedServerTimeMs = new Date().getTime() + offset;
});

Web

var offsetRef = firebase.database().ref(".info/serverTimeOffset");
offsetRef.on("value", (snap) => {
  var offset = snap.val();
  var estimatedServerTimeMs = new Date().getTime() + offset;
});

নমুনা উপস্থিতি অ্যাপ

সংযোগ অবস্থা পর্যবেক্ষণ এবং সার্ভার টাইমস্ট্যাম্পের সাথে সংযোগ বিচ্ছিন্নকরণ অপারেশনগুলিকে একত্রিত করে, আপনি একটি ব্যবহারকারীর উপস্থিতি সিস্টেম তৈরি করতে পারেন। এই সিস্টেমে, প্রতিটি ব্যবহারকারী একটি Realtime Database ক্লায়েন্ট অনলাইন কিনা তা নির্দেশ করার জন্য একটি ডাটাবেস অবস্থানে ডেটা সংরক্ষণ করে। ক্লায়েন্টরা অনলাইনে আসার সময় এই অবস্থানটিকে সত্য হিসাবে সেট করে এবং সংযোগ বিচ্ছিন্ন করার সময় একটি টাইমস্ট্যাম্প সেট করে। এই টাইমস্ট্যাম্পটি নির্দেশ করে যে প্রদত্ত ব্যবহারকারী শেষ কবে অনলাইনে ছিলেন।

মনে রাখবেন যে কোনও ব্যবহারকারীকে অনলাইনে চিহ্নিত করার আগে আপনার অ্যাপের ডিসকানেক্ট অপারেশনগুলি সারিবদ্ধ করা উচিত, যাতে উভয় কমান্ড সার্ভারে পাঠানোর আগে ক্লায়েন্টের নেটওয়ার্ক সংযোগ বিচ্ছিন্ন হয়ে গেলে কোনও রেস কন্ডিশন এড়ানো যায়।

এখানে একটি সহজ ব্যবহারকারী উপস্থিতি সিস্টেম রয়েছে:

Web

import { getDatabase, ref, onValue, push, onDisconnect, set, serverTimestamp } from "firebase/database";

// Since I can connect from multiple devices or browser tabs, we store each connection instance separately
// any time that connectionsRef's value is null (i.e. has no children) I am offline
const db = getDatabase();
const myConnectionsRef = ref(db, 'users/joe/connections');

// stores the timestamp of my last disconnect (the last time I was seen online)
const lastOnlineRef = ref(db, 'users/joe/lastOnline');

const connectedRef = ref(db, '.info/connected');
onValue(connectedRef, (snap) => {
  if (snap.val() === true) {
    // We're connected (or reconnected)! Do anything here that should happen only if online (or on reconnect)
    const con = push(myConnectionsRef);

    // When I disconnect, remove this device
    onDisconnect(con).remove();

    // Add this device to my connections list
    // this value could contain info about the device or a timestamp too
    set(con, true);

    // When I disconnect, update the last time I was seen online
    onDisconnect(lastOnlineRef).set(serverTimestamp());
  }
});

Web

// Since I can connect from multiple devices or browser tabs, we store each connection instance separately
// any time that connectionsRef's value is null (i.e. has no children) I am offline
var myConnectionsRef = firebase.database().ref('users/joe/connections');

// stores the timestamp of my last disconnect (the last time I was seen online)
var lastOnlineRef = firebase.database().ref('users/joe/lastOnline');

var connectedRef = firebase.database().ref('.info/connected');
connectedRef.on('value', (snap) => {
  if (snap.val() === true) {
    // We're connected (or reconnected)! Do anything here that should happen only if online (or on reconnect)
    var con = myConnectionsRef.push();

    // When I disconnect, remove this device
    con.onDisconnect().remove();

    // Add this device to my connections list
    // this value could contain info about the device or a timestamp too
    con.set(true);

    // When I disconnect, update the last time I was seen online
    lastOnlineRef.onDisconnect().set(firebase.database.ServerValue.TIMESTAMP);
  }
});