기업 환경에서는 안정적인 인터넷 연결을 당연한 것으로 여기는 경우가 많습니다. 그러나 실제 상황은 이러한 가정에 도전하는 경우가 많으며 잠재적으로 중요한 비즈니스 운영을 방해할 수 있습니다. 이 기사에서는 기존의 온라인 전용 ERP 시스템을 탄력적인 오프라인 지원 솔루션을 통해 보다 안정적인 시스템으로 전환한 방법을 자세히 설명합니다. IndexedDB와 같은 브라우저 기반 저장소 솔루션을 활용하고, 동기화 메커니즘을 채택하고, PWA(Progressive Web Apps)를 사용합니다.
처음에 시스템은 모든 비즈니스 로직이 백엔드에 상주하는 전통적인 클라이언트 서버 아키텍처를 따랐습니다. 이 아키텍처는 안정적인 연결이 가능한 환경에서 잘 작동하지만 몇 가지 과제가 있습니다.
이를 정의하기 위해 초기에는 사용할 수 없기 때문에 어떻게 하면 상황을 더 좋게 만들고 연결성 없이 수행할 수 있는지 즉흥적으로 검토해야 했습니다. PWA(Progressive Web Apps)를 사용하여 일부 인터넷이 필요한 오프라인 시스템을 구현하여 중요한 작업을 효과적으로 이동했습니다. 핵심 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) } }
서비스 워커: 이는 앱과 네트워크 간의 프록시 역할을 하며 리소스를 캐싱하고 요청을 가로채서 연결이 끊어진 동안에도 중요한 데이터에 계속 액세스할 수 있도록 하여 오프라인 기능을 활성화합니다.
//서비스 작업자는 쉽게 설정할 수 있습니다. 최근에는 기본적으로 nextJS 앱에 vite가 포함된 서비스 작업이 함께 제공되며 vite-pwa 플러그인을 사용할 수 있습니다
백그라운드 동기화: 이를 통해 네트워크를 다시 사용할 수 있을 때 데이터를 동기화할 수 있으므로 연결이 복원되면 거래가 손실되지 않고 자동으로 업데이트됩니다.
시스템 아키텍처 흐름
아키텍처는 초기화, 트랜잭션 처리, 동기화의 세 가지 주요 단계로 나누어졌습니다. 아래 순서도는 이러한 단계 사이의 데이터 흐름을 보여줍니다.
시스템이 시작되면 네트워크 연결을 확인합니다.
기기가 온라인이면 서버에서 최신 마스터 데이터를 가져와 로컬 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를 사용하여 전송 중 데이터 암호화
토큰 만료 및 보안 토큰 관리를 통해 오래되거나 만료된 토큰이 클라이언트 측 저장소에서 자동으로 제거되도록 합니다.
IndexedDB는 PWA의 클라이언트측 데이터 저장을 위한 확실한 선택이지만 애플리케이션의 복잡성과 요구 사항에 따라 사용할 수 있는 다른 옵션도 있습니다.
WebAssembly를 통한 SQLite(WASM): 일부 개발자는 특히 대규모 데이터 세트나 복잡한 쿼리를 처리할 때 고급 데이터 관리를 위해 WASM을 통해 SQLite를 사용하기로 선택합니다. 그러나 WASM을 통해 SQLite를 통합하면 성능 문제 및 브라우저 호환성(예: sqlite가 Notion을 더 빠르게 만든 방법)과 같은 추가적인 복잡성이 발생합니다.
Web Storage API(localStorage/sessionStorage): 복잡한 쿼리나 대규모 데이터 세트가 필요하지 않은 간단한 애플리케이션의 경우 Web Storage API가 실행 가능한 대안이 될 수 있습니다. 구현하기는 더 쉽지만 저장 용량 및 쿼리 기능 측면에서 제한이 있습니다.
웹 기술이 계속 발전함에 따라 이와 같은 애플리케이션의 가능성도 커지고 있습니다. 새로운 트렌드는 다음과 같습니다.
저는 이러한 기술이 어떻게 오프라인 및 분산 애플리케이션의 환경을 변화시킬지 탐구하고 싶습니다. 강력한 기계와 노트북의 급속한 발전으로 인해 우리는 향상된 컴퓨팅 성능을 활용하여 사용자에게 더욱 정교하고 효율적인 소프트웨어를 제공할 수 있는 기회를 얻었습니다. 동시에 우리는 모바일 장치와 성능이 떨어지는 장치에 맞춰 솔루션을 모든 플랫폼에서 액세스하고 최적화하는 것의 중요성을 잊어서는 안 됩니다. 잠재력은 엄청납니다. PWA로 가능한 것의 경계를 계속 확장하게 되어 기쁩니다.
우리는 그 일을 처리할 것입니다. Djuix.io를 백엔드로 사용하고 React/Angular를 프론트엔드로 사용하여 적절한 기본 흐름을 구현합니다. 놀라운 앱을 구축하기 위한 접근 방식을 지속적으로 강화하는 동안 추가 업데이트를 계속 지켜봐 주시기 바랍니다.
어쨌든 이 내용이 즐겁고 새로운 것을 배웠기를 바랍니다. 나는 확실히 그랬다. 여러분의 생각과 경험도 듣고 싶습니다.
그때까지
위 내용은 프로그레시브 웹 앱: 새로운 FE 시스템의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!