একজন পারফরম্যান্ট, অফলাইন অভিজ্ঞতার জন্য Google Base এবং Google Gears ব্যবহার করা

"বিল্ডিং বেটার অ্যাজাক্স অ্যাপ্লিকেশনস উইথ গুগল এপিআই" সিরিজের প্রথম নিবন্ধ।

ডিওন আলমার এবং পামেলা ফক্স, গুগল
জুন 2007

সম্পাদকের দ্রষ্টব্য: Google Gears API আর উপলব্ধ নেই

ভূমিকা

Google Gears-এর সাথে Google Base একত্রিত করে, আমরা প্রদর্শন করি কিভাবে একটি অ্যাপ্লিকেশন তৈরি করতে হয় যা অফলাইনে ব্যবহার করা যেতে পারে। এই নিবন্ধটি পড়ার পরে, আপনি Google Base API এর সাথে আরও পরিচিত হবেন, সেইসাথে ব্যবহারকারীর পছন্দ এবং ডেটা সংরক্ষণ এবং অ্যাক্সেস করার জন্য Google Gears কীভাবে ব্যবহার করবেন তা বুঝতে পারবেন।

অ্যাপটি বোঝা

এই অ্যাপটি বোঝার জন্য, আপনাকে প্রথমে Google Base- এর সাথে পরিচিত হতে হবে, যা মূলত পণ্য, রিভিউ, রেসিপি, ইভেন্ট এবং আরও অনেক কিছুর মতো আইটেমগুলির একটি বড় ডাটাবেস।

প্রতিটি আইটেম একটি শিরোনাম, বিবরণ, ডেটার মূল উৎসের লিঙ্ক (যদি বিদ্যমান থাকে) সহ টীকা করা হয়, এবং অতিরিক্ত বৈশিষ্ট্যগুলি যা প্রতি বিভাগ প্রকারের জন্য পরিবর্তিত হয়। Google Base এই সত্যটির সুবিধা নেয় যে একই বিভাগের আইটেমগুলি বৈশিষ্ট্যগুলির একটি সাধারণ সেট ভাগ করে-উদাহরণস্বরূপ, সমস্ত রেসিপিতে উপাদান রয়েছে৷ Google বেস আইটেম এমনকি মাঝে মাঝে Google ওয়েব অনুসন্ধান বা Google পণ্য অনুসন্ধান থেকে অনুসন্ধান ফলাফলে প্রদর্শিত হবে.

আমাদের ডেমো অ্যাপ্লিকেশান, বেস উইথ গিয়ারস , আপনাকে সঞ্চয় করতে এবং প্রদর্শন করতে দেয় সাধারণ অনুসন্ধানগুলি যা আপনি Google Base-এ "চকলেট" (yum) বা "সৈকতে হাঁটা" (রোমান্টিক!) সহ ব্যক্তিগত বিজ্ঞাপনগুলির সাথে রেসিপি খুঁজে পেতে পারেন৷ আপনি এটিকে একটি "গুগল বেস রিডার" হিসাবে ভাবতে পারেন যা আপনাকে অনুসন্ধানগুলিতে সদস্যতা নিতে দেয় এবং আপনি যখন অ্যাপটি পুনরায় পরিদর্শন করেন, বা যখন অ্যাপটি প্রতি 15 মিনিটে আপডেট করা ফিডগুলি সন্ধান করতে বের হয় তখন আপডেট ফলাফলগুলি দেখতে দেয়৷

অ্যাপটি প্রসারিত করতে চাইছেন এমন বিকাশকারীরা আরও বৈশিষ্ট্য যোগ করতে পারে, যেমন অনুসন্ধানের ফলাফলে নতুন ফলাফল থাকলে ব্যবহারকারীকে দৃশ্যত সতর্ক করা, ব্যবহারকারীকে বুকমার্ক (তারকা) প্রিয় আইটেমগুলি (অফলাইন + অনলাইন) করতে দেওয়া এবং ব্যবহারকারীকে বিভাগ-নির্দিষ্ট বৈশিষ্ট্য অনুসন্ধান করতে দেওয়া গুগল বেস।

গুগল বেস ডেটা API ফিড ব্যবহার করে

Google Base কে Google Base data API-এর সাথে প্রোগ্রাম্যাটিকভাবে জিজ্ঞাসা করা যেতে পারে, যা Google Data API ফ্রেমওয়ার্কের সাথে সঙ্গতিপূর্ণ। Google Data API প্রোটোকল ওয়েবে পড়া এবং লেখার জন্য একটি সাধারণ প্রোটোকল প্রদান করে এবং অনেক Google পণ্য দ্বারা ব্যবহৃত হয়: Picasa, স্প্রেডশীট, ব্লগার, ক্যালেন্ডার, নোটবুক এবং আরও অনেক কিছু।

Google Data API ফরম্যাট XML এবং Atom পাবলিশিং প্রোটোকলের উপর ভিত্তি করে, তাই বেশিরভাগ পঠন/লেখা ইন্টারঅ্যাকশনগুলি XML-এ হয়।

Google Data API-এর উপর ভিত্তি করে Google Base ফিডের একটি উদাহরণ হল:
http://www.google.com/base/feeds/snippets/-/products?bq=digital+camera

snippets ফিডের ধরন আমাদের আইটেমগুলির সর্বজনীনভাবে উপলব্ধ ফিড দেয়। -/products আমাদের ফিডকে পণ্য বিভাগে সীমাবদ্ধ করতে দেয়। এবং bq= প্যারামিটার আমাদের ফিডকে আরও সীমাবদ্ধ করতে দেয়, শুধুমাত্র "ডিজিটাল ক্যামেরা" কীওয়ার্ড ধারণকারী ফলাফলগুলিতে। আপনি যদি ব্রাউজারে এই ফিডটি দেখেন, তাহলে আপনি মিলিত ফলাফল সহ <entry> নোড ধারণকারী XML দেখতে পাবেন। প্রতিটি এন্ট্রিতে সাধারণ লেখক, শিরোনাম, বিষয়বস্তু এবং লিঙ্ক উপাদান থাকে, তবে অতিরিক্ত বিভাগ-নির্দিষ্ট বৈশিষ্ট্যের সাথে আসে (যেমন পণ্য বিভাগের আইটেমের জন্য "মূল্য")।

ব্রাউজারে XMLHttpRequest-এর ক্রস-ডোমেন সীমাবদ্ধতার কারণে, আমাদের জাভাস্ক্রিপ্ট কোডে www.google.com থেকে XML ফিডে সরাসরি পড়ার অনুমতি নেই। আমরা XML-এ পড়ার জন্য একটি সার্ভার-সাইড প্রক্সি সেট আপ করতে পারি এবং আমাদের অ্যাপের মতো একই ডোমেনের অবস্থানে এটিকে থুতু দিতে পারি, তবে আমরা সার্ভার-সাইড প্রোগ্রামিং সম্পূর্ণভাবে এড়াতে চাই। ভাগ্যক্রমে, একটি বিকল্প আছে।

অন্যান্য Google Data API-এর মতো, Google Base data API-এ স্ট্যান্ডার্ড XML ছাড়াও একটি JSON আউটপুট বিকল্প রয়েছে। আমরা আগে JSON ফর্ম্যাটে যে ফিড দেখেছি তার আউটপুট এই URL এ থাকবে:
http://www.google.com/base/feeds/snippets/-/products?bq=digital+camera&alt=json

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

JSON লোড হয়ে গেলে Google Data APIs আপনাকে কলব্যাক ফাংশন সহ একটি "json-in-script" আউটপুট নির্দিষ্ট করতে দেয়। এটি JSON আউটপুটকে কাজ করা আরও সহজ করে তোলে, কারণ আমরা গতিশীলভাবে পৃষ্ঠায় স্ক্রিপ্ট ট্যাগ যুক্ত করতে পারি এবং প্রতিটির জন্য বিভিন্ন কলব্যাক ফাংশন নির্দিষ্ট করতে পারি।

সুতরাং, গতিশীলভাবে একটি বেস API JSON ফিড পৃষ্ঠায় লোড করতে, আমরা নিম্নলিখিত ফাংশনটি ব্যবহার করতে পারি যা ফিড URL এর সাথে একটি স্ক্রিপ্ট ট্যাগ তৈরি করে ( alt callback মানগুলির সাথে যুক্ত) এবং এটিকে পৃষ্ঠায় যুক্ত করে।

function getJSON() {
  var script = document.createElement('script');

  var url = "http://www.google.com/base/feeds/snippets/-/products?bq=digital+camera";
  script.setAttribute('src', url + "&alt=json-in-script&callback=listResults");
  script.setAttribute('type', 'text/JavaScript');
  document.documentElement.firstChild.appendChild(script);
}

সুতরাং আমাদের কলব্যাক ফাংশন listResults এখন শুধুমাত্র প্যারামিটার হিসাবে JSON-এর মাধ্যমে পুনরাবৃত্তি করতে পারে-এবং একটি বুলেটযুক্ত তালিকায় পাওয়া প্রতিটি এন্ট্রিতে তথ্য প্রদর্শন করতে পারে।

  function listTasks(root) {
    var feed = root.feed;
    var html = [''];
    html.push('<ul>');
    for (var i = 0; i < feed.entry.length; ++i) {
      var entry = feed.entry[i];
      var title = entry.title.$t;
      var content = entry.content.$t;
      html.push('<li>', title, ' (', content, ')</li>');
    }
    html.push('</ul>');

    document.getElementById("agenda").innerHTML = html.join("");
  }

Google Gears যোগ করা হচ্ছে

এখন যেহেতু আমাদের কাছে একটি অ্যাপ্লিকেশন রয়েছে যা Google Data API-এর মাধ্যমে Google Base-এর সাথে কথা বলতে সক্ষম, আমরা এই অ্যাপ্লিকেশনটিকে অফলাইনে চালানোর জন্য সক্ষম করতে চাই৷ এখানেই Google Gears আসে।

অফলাইনে যেতে পারে এমন একটি অ্যাপ্লিকেশন লেখার ক্ষেত্রে বিভিন্ন আর্কিটেকচারের পছন্দ রয়েছে। আপনি নিজেকে প্রশ্ন জিজ্ঞাসা করবেন কিভাবে অ্যাপ্লিকেশনটি অনলাইন বনাম অফলাইনে কাজ করা উচিত (যেমন এটি কি ঠিক একই কাজ করে? কিছু বৈশিষ্ট্য অক্ষম করা আছে, যেমন অনুসন্ধান? আপনি কীভাবে সিঙ্কিং পরিচালনা করবেন?)

আমাদের ক্ষেত্রে, আমরা নিশ্চিত করতে চেয়েছিলাম যে Gears ব্যতীত ব্রাউজারে ব্যবহারকারীরা এখনও অ্যাপটি ব্যবহার করতে পারেন, সেইসঙ্গে যে ব্যবহারকারীদের কাছে প্লাগ-ইন রয়েছে তাদের অফলাইন ব্যবহারের সুবিধা এবং আরও প্রতিক্রিয়াশীল UI প্রদান করে৷

আমাদের স্থাপত্য এই মত দেখায়:

  • আমাদের কাছে একটি জাভাস্ক্রিপ্ট অবজেক্ট রয়েছে যা আপনার অনুসন্ধানের প্রশ্নগুলি সংরক্ষণ করার এবং এই প্রশ্নগুলি থেকে ফলাফলগুলি ফিরিয়ে দেওয়ার দায়িত্বে রয়েছে৷
  • আপনার যদি Google Gears ইনস্টল করা থাকে, তাহলে আপনি একটি Gears সংস্করণ পাবেন যা স্থানীয় ডাটাবেসে সবকিছু সঞ্চয় করে।
  • যদি আপনার কাছে Google Gears ইনস্টল না থাকে, তাহলে আপনি একটি সংস্করণ পাবেন যা একটি কুকিতে প্রশ্নগুলিকে সংরক্ষণ করে এবং সম্পূর্ণ ফলাফলগুলিকে মোটেও সংরক্ষণ করে না (অতএব কিছুটা ধীর প্রতিক্রিয়াশীলতা), কারণ ফলাফলগুলি কুকিতে সংরক্ষণ করার জন্য খুব বড়।
এই স্থাপত্যের যেটা চমৎকার তা হল যে আপনাকে পুরো দোকান জুড়ে if (online) {} চেক করতে হয় না। পরিবর্তে, অ্যাপ্লিকেশনটিতে একটি Gears চেক আছে, এবং তারপর সঠিক অ্যাডাপ্টার ব্যবহার করা হয়।


একটি গিয়ারস স্থানীয় ডাটাবেস ব্যবহার করা

Gears-এর একটি উপাদান হল স্থানীয় SQLite ডাটাবেস যা এম্বেড করা এবং আপনার ব্যবহারের জন্য প্রস্তুত। আপনি যদি পূর্বে MySQL বা Oracle এর মতো সার্ভার-সাইড ডাটাবেসের জন্য API ব্যবহার করে থাকেন তবে একটি সাধারণ ডাটাবেস API আছে যা আপনার কাছে পরিচিত মনে হবে।

একটি স্থানীয় ডাটাবেস ব্যবহার করার পদক্ষেপগুলি বেশ সহজ:

  • Google Gears অবজেক্ট শুরু করুন
  • একটি ডাটাবেস কারখানা অবজেক্ট পান, এবং একটি ডাটাবেস খুলুন
  • এসকিউএল অনুরোধগুলি কার্যকর করা শুরু করুন

এর মধ্যে দিয়ে দ্রুত হাঁটা যাক.


Google Gears অবজেক্ট শুরু করুন

আপনার অ্যাপ্লিকেশনটি সরাসরি /gears/samples/gears_init.js এর বিষয়বস্তুতে পড়তে হবে, অথবা আপনার নিজস্ব জাভাস্ক্রিপ্ট ফাইলে কোড পেস্ট করে। একবার আপনি <script src="..../gears_init.js" type="text/JavaScript"></script> চলে গেলে, আপনার google.gears নামস্থানে অ্যাক্সেস থাকবে।


একটি ডাটাবেস ফ্যাক্টরি অবজেক্ট পান এবং একটি ডাটাবেস
var db = google.gears.factory.create('beta.database', '1.0');
db.open('testdb');
খুলুন

এই একটি কল আপনাকে একটি ডাটাবেস অবজেক্ট দেবে যা আপনাকে একটি ডাটাবেস স্কিমা খুলতে দেয়। আপনি যখন ডাটাবেসগুলি খুলবেন, সেগুলি একই মূল নীতির নিয়মের মাধ্যমে স্কোপ করা হয়, তাই আপনার "testdb" আমার "testdb" এর সাথে সংঘর্ষে লিপ্ত হবে না।


এসকিউএল অনুরোধগুলি কার্যকর করা শুরু করুন

এখন আমরা ডাটাবেসে SQL অনুরোধ পাঠাতে প্রস্তুত। যখন আমরা "নির্বাচন" অনুরোধ পাঠাই, আমরা একটি ফলাফল সেট ফিরে পাই যা আমরা কাঙ্ক্ষিত ডেটার জন্য পুনরাবৃত্তি করতে পারি:

var rs = db.execute('select * from foo where name = ?', [ name ]);

আপনি নিম্নলিখিত পদ্ধতিগুলির সাথে ফিরে আসা ফলাফল সেটে কাজ করতে পারেন:

boolean isValidRow()
void next()
void close()
int fieldCount()
string fieldName(int fieldIndex)
variant field(int fieldIndex)
variant fieldByName(string fieldname)

আরো বিস্তারিত জানার জন্য, অনুগ্রহ করে ডাটাবেস মডিউল API ডকুমেন্টেশন দেখুন। (সম্পাদকের দ্রষ্টব্য: Google Gears API আর উপলব্ধ নেই )।


নিম্ন স্তরের API এনক্যাপসুলেট করতে GearsDB ব্যবহার করা

আমরা কিছু সাধারণ ডাটাবেসের কাজগুলিকে এনক্যাপসুলেট করতে এবং আরও সুবিধাজনক করতে চেয়েছিলাম। উদাহরণ স্বরূপ,

  • আমরা অ্যাপ্লিকেশনটি ডিবাগ করার সময় তৈরি করা SQL লগ করার একটি সুন্দর উপায় চাই।
  • আমরা সব জায়গায় try{}catch(){} করার পরিবর্তে এক জায়গায় ব্যতিক্রমগুলি পরিচালনা করতে চেয়েছিলাম।
  • আমরা ডেটা পড়ার বা লেখার সময় ফলাফল সেটের পরিবর্তে জাভাস্ক্রিপ্ট অবজেক্টের সাথে ডিল করতে চেয়েছিলাম।

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

প্রাথমিক সেটআপ

আমাদের window.onload কোডে, আমাদের নিশ্চিত করতে হবে যে আমরা যে ডাটাবেস টেবিলের উপর নির্ভর করি সেগুলি যথাস্থানে আছে। নিম্নলিখিত কোডটি চলার সময় ব্যবহারকারীর যদি গিয়ারস ইনস্টল করা থাকে, তাহলে তারা একটি GearsBaseContent অবজেক্ট তৈরি করবে:

content = hasGears() ? new GearsBaseContent() : new CookieBaseContent();

এর পরে, আমরা ডাটাবেস খুলি এবং টেবিল তৈরি করি যদি সেগুলি ইতিমধ্যে বিদ্যমান না থাকে:

db = new GearsDB('gears-base'); // db is defined as a global for reuse later!

if (db) {
  db.run('create table if not exists BaseQueries' +
         ' (Phrase varchar(255), Itemtype varchar(100))');
  db.run('create table if not exists BaseFeeds' + 
         ' (id varchar(255), JSON text)');
}

এই মুহুর্তে, আমরা নিশ্চিত যে আমাদের কাছে প্রশ্ন এবং ফিডগুলি সংরক্ষণ করার জন্য একটি টেবিল রয়েছে। new GearsDB(name) কোডটি প্রদত্ত নামের সাথে একটি ডাটাবেস খোলার সময়কে এনক্যাপসুলেট করবে। run মেথড নিম্ন স্তরের execute মেথড র‍্যাপ করে কিন্তু কনসোলে ডিবাগিং আউটপুট এবং ট্র্যাপিং এক্সেপশনও পরিচালনা করে।


একটি অনুসন্ধান শব্দ যোগ করা হচ্ছে

আপনি যখন প্রথম অ্যাপটি চালাবেন, তখন আপনার কোনো অনুসন্ধান থাকবে না। আপনি যদি পণ্যগুলিতে একটি Nintendo Wii অনুসন্ধান করার চেষ্টা করেন, আমরা এই অনুসন্ধান শব্দটিকে বেসকোয়েরি টেবিলে সংরক্ষণ করব।

addQuery পদ্ধতির Gears সংস্করণ ইনপুট গ্রহণ করে এবং insertRow মাধ্যমে সংরক্ষণ করে এটি করে।

var searchterm = { Phrase: phrase, Itemtype: itemtype };
db.insertRow('BaseQueries', searchterm); 

insertRow একটি জাভাস্ক্রিপ্ট অবজেক্ট ( searchterm ) নেয় এবং এটিকে আপনার জন্য টেবিলে ঢোকানোর ব্যবস্থা করে। এটি আপনাকে সীমাবদ্ধতা সংজ্ঞায়িত করতে দেয় (উদাহরণস্বরূপ, একাধিক "বব" এর স্বতন্ত্রতা-ব্লক সন্নিবেশ)। যাইহোক, বেশিরভাগ সময় আপনি ডাটাবেসের মধ্যেই এই সীমাবদ্ধতাগুলি পরিচালনা করবেন।


সমস্ত অনুসন্ধান শর্তাদি পাচ্ছেন৷

আপনার অতীত অনুসন্ধানের তালিকা পূরণ করতে, আমরা selectAll নামে একটি সুন্দর নির্বাচনী মোড়ক ব্যবহার করি :

GearsBaseContent.prototype.getQueries = function() {
  return this.db.selectAll('select * from BaseQueries');
}

এটি ডাটাবেসের সারিগুলির সাথে মেলে এমন জাভাস্ক্রিপ্ট অবজেক্টের একটি অ্যারে ফিরিয়ে দেবে (যেমন [ { Phrase: 'Nintendo Wii', Itemtype: 'product' }, { ... }, ...]

এই ক্ষেত্রে, সম্পূর্ণ তালিকা ফেরত দেওয়া ভাল। কিন্তু যদি আপনার কাছে প্রচুর ডেটা থাকে, তাহলে আপনি সম্ভবত নির্বাচিত কলে একটি কলব্যাক ব্যবহার করতে চাইবেন যাতে আপনি প্রতিটি ফেরত সারিতে কাজ করতে পারেন যেমন এটি আসে:

 db.selectAll('select * from BaseQueries where Itemtype = ?', ['product'], function(row) {
  ... do something with this row ...
});

এখানে GearsDB-তে আরও কিছু সহায়ক নির্বাচন পদ্ধতি রয়েছে:

selectOne(sql, args) প্রথম/একটি মিলে যাওয়া জাভাস্ক্রিপ্ট অবজেক্ট ফেরত দিন
selectRow(table, where, args, select) সাধারণত SQL উপেক্ষা করার জন্য সাধারণ ক্ষেত্রে ব্যবহৃত হয়
selectRows(table, where, args, callback, select) SelectRow এর মতই, কিন্তু একাধিক ফলাফলের জন্য।

একটি ফিড লোড হচ্ছে৷

যখন আমরা Google Base থেকে ফলাফল ফিড পাই, তখন আমাদের এটি ডাটাবেসে সংরক্ষণ করতে হবে:

content.setFeed({ id: id, JSON: json.toJSONString() });

... which calls ...

GearsBaseContent.prototype.setFeed = function(feed) {
  this.db.forceRow('BaseFeeds', feed);
}

আমরা প্রথমে JSON ফিড নিই এবং toJSONString পদ্ধতি ব্যবহার করে স্ট্রিং হিসাবে ফেরত দিই। তারপর আমরা feed অবজেক্ট তৈরি করি এবং সেটিকে forceRow পদ্ধতিতে পাস করি। forceRow একটি এন্ট্রি সন্নিবেশ করবে যদি একটি ইতিমধ্যে বিদ্যমান না থাকে, অথবা একটি বিদ্যমান এন্ট্রি আপডেট করবে।


অনুসন্ধান ফলাফল প্রদর্শন করা হচ্ছে

আমাদের অ্যাপটি পৃষ্ঠার ডান প্যানেলে একটি প্রদত্ত অনুসন্ধানের ফলাফল প্রদর্শন করে। এখানে আমরা কিভাবে অনুসন্ধান শব্দের সাথে যুক্ত ফিড পুনরুদ্ধার করি:

GearsBaseContent.prototype.getFeed = function(url) {
  var row = this.db.selectRow('BaseFeeds', 'id = ?', [ url ]);
  return row.JSON;
}

এখন যেহেতু আমাদের কাছে একটি সারির জন্য JSON আছে, আমরা বস্তুগুলি ফিরে পেতে এটিকে eval() করতে পারি:

eval("var json = " + jsonString + ";");

আমরা রেসে চলে এসেছি এবং JSON থেকে আমাদের পৃষ্ঠায় অভ্যন্তরীণ HTMLিং সামগ্রী শুরু করতে পারি৷


অফলাইন অ্যাক্সেসের জন্য রিসোর্স স্টোর ব্যবহার করা

যেহেতু আমরা একটি স্থানীয় ডাটাবেস থেকে সামগ্রী পাচ্ছি, তাই এই অ্যাপটি অফলাইনেও কাজ করা উচিত, তাই না?

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

এটি করার জন্য, আমরা লোকাল সার্ভার উপাদান ব্যবহার করি এবং আমাদের সংস্থানগুলি ক্যাপচার করি। আপনি যখন কোনো সম্পদ (যেমন HTML এবং JavaScript) ক্যাপচার করেন (যেমন অ্যাপ্লিকেশন চালানোর জন্য), Gears এই আইটেমগুলিকে সেভ করবে এবং ব্রাউজার থেকে সেগুলি ফেরত দেওয়ার অনুরোধগুলিও আটকে দেবে৷ স্থানীয় সার্ভার ট্রাফিক পুলিশ হিসাবে কাজ করবে এবং স্টোর থেকে সংরক্ষিত বিষয়বস্তু ফিরিয়ে দেবে।

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

আমাদের সংস্থানগুলি ক্যাপচার করতে, GearsBaseContent অবজেক্ট করবে:

  1. ফাইলগুলির একটি অ্যারে সেট আপ করুন যা ক্যাপচার করার প্রয়োজন
  2. একটি স্থানীয় সার্ভার তৈরি করুন
  3. একটি নতুন রিসোর্সস্টোর খুলুন বা তৈরি করুন
  4. দোকানে পৃষ্ঠাগুলি ক্যাপচার করতে কল করুন
// Step 1
this.storeName = 'gears-base';
this.pageFiles = [
  location.pathname,
  'gears_base.js',
  '../scripts/gears_db.js',
  '../scripts/firebug/firebug.js',
  '../scripts/firebug/firebug.html',
  '../scripts/firebug/firebug.css',
  '../scripts/json_util.js',    'style.css',
  'capture.gif' ];

// Step 2
try {
  this.localServer = google.gears.factory.create('beta.localserver', '1.0');
} catch (e) {
  alert('Could not create local server: ' + e.message);
  return;
}

// Step 3
this.store = this.localServer.openStore(this.storeName) || this.localServer.createStore(this.storeName);

// Step 4
this.capturePageFiles();

... which calls ...

GearsBaseContent.prototype.capturePageFiles = function() {
  this.store.capture(this.pageFiles, function(url, success, captureId) {
    console.log(url + ' capture ' + (success ? 'succeeded' : 'failed'));
  });
}

এখানে উল্লেখ করা গুরুত্বপূর্ণ যে আপনি শুধুমাত্র আপনার নিজের ডোমেনে সম্পদ ক্যাপচার করতে পারেন। আমরা এই সীমাবদ্ধতার মধ্যে পড়েছিলাম যখন আমরা GearsDB JavaScript ফাইলটি এর SVN ট্রাঙ্কের আসল "gears_db.js" ফাইল থেকে সরাসরি অ্যাক্সেস করার চেষ্টা করি। সমাধানটি সহজ, অবশ্যই: আপনাকে যেকোনো বাহ্যিক সংস্থান ডাউনলোড করতে হবে এবং সেগুলিকে আপনার ডোমেনের অধীনে রাখতে হবে। মনে রাখবেন যে 302 বা 301 রিডাইরেক্ট কাজ করবে না, কারণ LocalServer শুধুমাত্র 200 (Success) বা 304 (Not Modified) সার্ভার কোড গ্রহণ করে।

এর প্রভাব রয়েছে। আপনি images.yourdomain.com এ আপনার ছবি রাখলে, আপনি সেগুলি ক্যাপচার করতে পারবেন না। www1 এবং www2 একে অপরকে দেখতে পারে না। আপনি সার্ভার-সাইড প্রক্সি সেট আপ করতে পারেন, কিন্তু এটি আপনার অ্যাপ্লিকেশনটিকে একাধিক ডোমেনে বিভক্ত করার উদ্দেশ্যকে পরাজিত করবে।

অফলাইন অ্যাপ্লিকেশন ডিবাগ করা হচ্ছে

একটি অফলাইন অ্যাপ্লিকেশন ডিবাগ করা একটু বেশি জটিল। পরীক্ষা করার জন্য এখন আরও পরিস্থিতি রয়েছে:

  • আমি অনলাইনে অ্যাপটি সম্পূর্ণভাবে ক্যাশে চলছে
  • আমি অনলাইনে আছি কিন্তু অ্যাপটি অ্যাক্সেস করিনি, এবং ক্যাশে কিছুই নেই
  • আমি অফলাইনে আছি কিন্তু অ্যাপটি অ্যাক্সেস করেছি
  • আমি অফলাইনে আছি এবং কখনই অ্যাপটি অ্যাক্সেস করিনি (হতে ভালো জায়গা নয়!)

জীবনকে সহজ করার জন্য, আমরা নিম্নলিখিত প্যাটার্ন ব্যবহার করেছি:

  • আমরা ফায়ারফক্সে (বা আপনার পছন্দের ব্রাউজার) ক্যাশে অক্ষম করি যখন আমাদের নিশ্চিত করতে হবে যে ব্রাউজারটি কেবল ক্যাশে থেকে কিছু বাছাই করছে না।
  • আমরা ফায়ারবাগ (এবং অন্যান্য ব্রাউজারে পরীক্ষার জন্য ফায়ারবাগ লাইট) ব্যবহার করে ডিবাগ করি; আমরা সব জায়গায় console.log() ব্যবহার করি এবং কনসোলের জন্য সনাক্ত করি
  • আমরা এতে সহায়ক জাভাস্ক্রিপ্ট কোড যোগ করি:
    • আমাদের ডাটাবেস পরিষ্কার করতে এবং একটি পরিষ্কার স্লেট দিতে অনুমতি দিন
    • ক্যাপচার করা ফাইলগুলি সরান, তাই আপনি যখন পুনরায় লোড করেন, তখন সেগুলি আবার পেতে ইন্টারনেটে চলে যায় (যখন আপনি বিকাশে পুনরাবৃত্তি করছেন তখন দরকারী;)

আপনার Gears ইনস্টল করা থাকলেই ডিবাগ উইজেটটি পৃষ্ঠার বাম দিকে প্রদর্শিত হয়৷ এতে ক্লিন-আপ কোডের কলআউট রয়েছে:

GearsBaseContent.prototype.clearServer = function() {
  if (this.localServer.openStore(this.storeName)) {
    this.localServer.removeStore(this.storeName);
    this.store = null;
  }
}

GearsBaseContent.prototype.clearTables = function() {
  if (this.db) {
    this.db.run('delete from BaseQueries');
    this.db.run('delete from BaseFeeds');
  }
  displayQueries();
}

উপসংহার

আপনি দেখতে পাচ্ছেন যে Google Gears এর সাথে কাজ করা আসলে মোটামুটি সহজ। আমরা ডেটাবেস উপাদানকে আরও সহজ করতে GearsDB ব্যবহার করেছি এবং ম্যানুয়াল রিসোর্সস্টোর ব্যবহার করেছি, যা আমাদের উদাহরণের জন্য ঠিক কাজ করেছে।

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

আমরা নিম্নলিখিত ফলাফল সহ আমাদের ফাইলগুলির ট্র্যাক রাখতে ManagedResourceStore ব্যবহার করতে পারতাম:

  • আমরা ভাল নাগরিক হব এবং ভবিষ্যতের পরিচ্ছন্ন আপগ্রেডগুলি সক্ষম করতে আমাদের ফাইলগুলিকে সংস্করণ করব
  • ManagedResourceStore-এর একটি বৈশিষ্ট্য রয়েছে যা আপনাকে কন্টেন্টের অন্য অংশের একটি URL নামে পরিচিত করতে দেয়। একটি বৈধ আর্কিটেকচার পছন্দ হবে gears_base.js একটি নন-Gears সংস্করণ, এবং উপনাম যাতে Gears নিজেই gears_base_withgears.js ডাউনলোড করবে যার সমস্ত অফলাইন সমর্থন থাকবে।
আমাদের অ্যাপের জন্য, আমরা অনুভব করেছি যে শুধুমাত্র একটি ইন্টারফেস থাকা এবং সেই ইন্টারফেসটিকে দুটি উপায়ে বাস্তবায়ন করা সহজ।

আমরা আশা করি আপনি গিয়ারিং আপ অ্যাপ্লিকেশনগুলি মজাদার এবং সহজ পেয়েছেন! আপনার যদি প্রশ্ন থাকে বা শেয়ার করার জন্য কোনো অ্যাপ থাকে তাহলে অনুগ্রহ করে Google Gears ফোরামে আমাদের সাথে যোগ দিন।