企業環境では、安定したインターネット接続が与えられたものであると考えることがよくあります。ただし、実際の状況ではこの前提が覆されることが多く、重要な業務運営が中断される可能性があります。この記事では、従来のオンラインのみの ERP システムを、回復力のあるオフライン対応ソリューションを備えたより信頼性の高いシステムにどのように変換したかについて詳しく説明します。 IndexedDB などのブラウザベースのストレージ ソリューションを活用し、同期メカニズムを採用し、プログレッシブ Web アプリ (PWA) を使用します。
当初、システムは、すべてのビジネス ロジックがバックエンドに存在する従来のクライアント サーバー アーキテクチャに従っていました。このアーキテクチャは、接続が信頼できる環境ではうまく機能しますが、次のようないくつかの課題がありました。
これを定義するにあたり、どうすれば事態を改善できるかを即興で検討する必要があり、また、最初は利用できないため、共謀を避けて実行する必要がありました。プログレッシブ Web アプリ (PWA) を使用してインターネットが必要なオフライン システムを実装し、重要な問題を効果的に解決しました。データの整合性とコア ERP システムとの同期を維持しながら、ビジネス ロジックをフロントエンドに送信します。
IndexedDB: オフライン データ ストレージとキャッシュには、Dexie.js ライブラリ経由で IndexedDB を使用し、構造化データ ストレージをサポートする堅牢なクライアント側データベースを提供しました。以下は、Dexie
を使用してデータベースをセットアップする方法の簡単な例です。
// Initialize IndexedDB using Dexie.js import Dexie from 'dexie'; interface LocalUsers{ id:string; name:string; role:string; dob:string; phone_no:string } interface LocalTrx { id: string; syncId:string; created_at:string; amount:string; isSynced:boolean; modified:string; } export class ArticleDatabase extends Dexie { transaction!: Table<LocalTrx>; users!: Table<LocalUsers>; constructor(){ super("articleDB") } this.version(1).stores({ // define the fields you'll like to query by or find items by within the indexDB transactions: 'id, date, amount, isSynced', users: 'id, name, role' }); } //create the db export const db=new ArticleDatabase() // Open the database db.open().then(() => { console.log("Database opened successfully!"); }) .catch((error) => { console.error("Failed to open database:", error); }); // Adding a new transaction to IndexedDB import db from ../db async function addTransaction(transaction) { try { const trx = await db.transactions.add(transaction) console.log("Trx added", trx) } catch (err) { console.log("Failed creating trx", err) } }
Service Worker: これらはアプリとネットワークの間のプロキシとして機能し、リソースをキャッシュし、リクエストをインターセプトすることでオフライン機能を有効にし、切断中に重要なデータにアクセスできるようにします。
//サービスワーカーは簡単にセットアップできます。最近デフォルトで nextJS アプリには vite でのサービスワークが付属しており、vite-pwa プラグインを使用できます
バックグラウンド同期: これにより、ネットワークが再び利用可能になったときにデータを同期できるため、トランザクションが失われず、接続が回復すると更新が自動的に行われます。
システムアーキテクチャフロー
アーキテクチャは、初期化、トランザクション処理、同期の 3 つの主要なフェーズに分かれていました。以下のフローチャートは、これらのステージ間でデータがどのように流れるかを示しています。
システムが起動すると、ネットワーク接続がチェックされます:
デバイスがオンラインの場合、サーバーから最新のマスター データを取得し、ローカルの IndexedDB を更新します。
デバイスがオフラインの場合は、IndexedDB からデータをロードし、ユーザーが中断することなく作業を継続できるようにします。
ユーザーが新しいトランザクションを実行するとき:
ローカル データは検証され、IndexedDB に保存されます。
楽観的な UI アップデートを使用して結果がユーザーに即座に表示され、スムーズで応答性の高いエクスペリエンスが提供されます。
接続が回復すると:
データは、同期ボタンを手動でクリックするか、一定の期間後にサーバーとバッチで同期されます。
同期が失敗した場合 (接続が遅いなどの理由で)、トランザクションは失敗したトランザクションのリストに追加され、後で再試行されます。
当社はフロントエンドですべてを管理しているため、顧客情報の保護に関して当社のサービスはどの程度依存していますか。
認証と認可
どのような企業システムにおいても、ユーザーの機密情報を保護することは重要です。私たちのソリューションは以下を保証します:
JWT ベースの認証 は安全なユーザー セッションに使用されます。
ロールベースのアクセス制御 により、許可されたユーザーのみが特定のアクションを実行できるようになります。
安全なトークン ストレージは、セキュリティを強化するために、localStorage などのブラウザベースのメカニズムを使用して処理されます。
ローカルに保存されたトークンを使用するリスクを軽減するために、次のことを行います。
ログアウト時にユーザー トークンの安全な削除をトリガーします。
セッションが終了するとき、またはユーザーがシステムからログアウトするときに、機密データが IndexedDB から削除されるようにします。注: トランザクションが同期されていない場合は、ログインしているユーザーにその旨が表示され、ログアウトする前に同期が強制されます。
データの整合性と競合の解決
クライアントとサーバー間でデータを同期すると、特に複数のデバイスまたはユーザーがオフラインで同じデータに変更を加えている場合、データの整合性に関する潜在的な問題が発生します。これに対処するには:
同期前にすべての取引の詳細 (数量、金額など) を検証し、矛盾がないことを確認します。
同期中の重複を防ぐために、各トランザクションに一意の ID を割り当てます。
オフライン中に複数のデバイスでデータ変更が行われる状況に対処するために、競合解決戦略が採用されています。たとえば、タイムスタンプのアプローチを使用します。
//オフラインはシステムの重要な部分であるため、オフラインが最初に考慮されるように努めます。
// Initialize IndexedDB using Dexie.js import Dexie from 'dexie'; interface LocalUsers{ id:string; name:string; role:string; dob:string; phone_no:string } interface LocalTrx { id: string; syncId:string; created_at:string; amount:string; isSynced:boolean; modified:string; } export class ArticleDatabase extends Dexie { transaction!: Table<LocalTrx>; users!: Table<LocalUsers>; constructor(){ super("articleDB") } this.version(1).stores({ // define the fields you'll like to query by or find items by within the indexDB transactions: 'id, date, amount, isSynced', users: 'id, name, role' }); } //create the db export const db=new ArticleDatabase() // Open the database db.open().then(() => { console.log("Database opened successfully!"); }) .catch((error) => { console.error("Failed to open database:", error); }); // Adding a new transaction to IndexedDB import db from ../db async function addTransaction(transaction) { try { const trx = await db.transactions.add(transaction) console.log("Trx added", trx) } catch (err) { console.log("Failed creating trx", err) } }
ネットワークセキュリティ
接続が回復するとデータがネットワーク経由で送信されることを考慮して、次のことを確保しました。
乱用を防止し、リクエストが多すぎて 429 応答でサーバーが過負荷にならないようにするためのレート制限。これが、私たちが最初にバッチ更新を使用した理由です。
SSL/TLS を使用した転送中のデータの暗号化。
トークンの有効期限と安全なトークン管理により、古いトークンや期限切れのトークンがクライアント側のストレージから自動的に削除されます。
PWA のクライアント側データ ストレージには IndexedDB が確実な選択肢ですが、アプリケーションの複雑さと要件に応じて他のオプションも利用できます。
WebAssembly 経由の SQLite (WASM): 一部の開発者は、特に大規模なデータセットや複雑なクエリを扱う場合、より高度なデータ管理のために WASM 経由で SQLite を使用することを選択します。ただし、WASM 経由で SQLite を統合すると、パフォーマンスの問題やブラウザの互換性など、さらなる複雑さが生じます (例: sqlite が Notion をどのように高速化したか)。
Web Storage API (localStorage/sessionStorage): 複雑なクエリや大規模なデータセットを必要としない単純なアプリケーションの場合、Web Storage API が実行可能な代替手段となる可能性があります。実装は簡単ですが、ストレージ容量とクエリ機能の点で制限があります。
Web テクノロジーが進化し続けるにつれて、このようなアプリケーションの可能性も高まります。新しいトレンドには次のものがあります:
私自身、これらのテクノロジーがオフラインおよび分散アプリケーションの状況をどのように変革するのかを探るのが待ちきれません。強力なマシンやラップトップの急速な進歩により、私たちはこの増大したコンピューティング能力を利用して、さらに洗練された効率的なソフトウェアをユーザーに提供する機会を得ています。同時に、モバイル デバイスや機能の低いデバイスに対応し、当社のソリューションがすべてのプラットフォームでアクセス可能で最適化されていることを保証することの重要性を忘れてはなりません。可能性は非常に大きく、PWA で可能なことの限界を押し広げ続けることに興奮しています。
私たちは物事を取り上げます。バックエンドとして Djuix.io を使用し、フロントエンドとして React / Angular を使用して、適切な基本フローを実装します。素晴らしいアプリを構築するためのアプローチを強化し続けるため、今後の最新情報にご期待ください。
とにかく、これを楽しんで、何か新しいことを学んでいただければ幸いです。確かにそうでした。あなたの考えや経験もぜひ聞きたいです。
それまでは。
以上がプログレッシブ Web アプリ: 新しい FE システムの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。