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

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

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

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

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

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

WebWeb
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!");
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 সঠিকভাবে সংযুক্ত করা হয়েছে তা নিশ্চিত করতে আপনার অ্যাপটি রাইট অপারেশনে কলব্যাক ব্যবহার করতে পারে:

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

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

WebWeb
const onDisconnectRef = onDisconnect(presenceRef);
onDisconnectRef.set("I disconnected");
// some time later when we change our minds
onDisconnectRef.cancel();
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 ক্লায়েন্টের সংযোগের অবস্থা পরিবর্তনের সময় আপডেট করা হয়। এখানে একটি উদাহরণ:

WebWeb
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");
  }
});
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 ক্লায়েন্ট সংযোগ বিচ্ছিন্ন হওয়ার সময়টি নির্ভরযোগ্যভাবে নোট করার একটি সহজ উপায় প্রদান করে:

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

const db = getDatabase();
const userLastOnlineRef = ref(db, "users/joe/lastOnline");
onDisconnect(userLastOnlineRef).set(serverTimestamp());
var userLastOnlineRef = firebase.database().ref("users/joe/lastOnline");
userLastOnlineRef.onDisconnect().set(firebase.database.ServerValue.TIMESTAMP);

ঘড়ি Skew

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

WebWeb
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;
});
var offsetRef = firebase.database().ref(".info/serverTimeOffset");
offsetRef.on("value", (snap) => {
  var offset = snap.val();
  var estimatedServerTimeMs = new Date().getTime() + offset;
});

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

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

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

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

WebWeb
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());
  }
});
// 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);
  }
});