353 lines
11 KiB
Markdown
353 lines
11 KiB
Markdown
|
|
# 🏗️ Архитектура Flutter WebView Bridge
|
|||
|
|
|
|||
|
|
## 📋 Обзор системы
|
|||
|
|
|
|||
|
|
Flutter WebView Bridge - это система для безопасной коммуникации между Flutter Host приложением и Flutter Web приложениями через WebView. Система обеспечивает типобезопасность, изоляцию payload'ов и простоту использования.
|
|||
|
|
|
|||
|
|
## 🏛️ Архитектурные принципы
|
|||
|
|
|
|||
|
|
### 1. Изоляция payload'ов
|
|||
|
|
- Web приложения видят только свои payload'ы
|
|||
|
|
- Host приложение контролирует доступ к payload'ам
|
|||
|
|
- Безопасная архитектура без утечек данных
|
|||
|
|
|
|||
|
|
### 2. Типобезопасность
|
|||
|
|
- Все payload'ы типизированы
|
|||
|
|
- Компилятор проверяет корректность
|
|||
|
|
- Автодополнение в IDE
|
|||
|
|
|
|||
|
|
### 3. Модульность
|
|||
|
|
- Переиспользуемые компоненты
|
|||
|
|
- Легкое расширение функциональности
|
|||
|
|
- Четкое разделение ответственности
|
|||
|
|
|
|||
|
|
## 📦 Структура пакетов
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
packages/
|
|||
|
|
├── bridge_core/ # Базовые типы и сериализация
|
|||
|
|
├── payloads_shared/ # Общие payload'ы для всех приложений
|
|||
|
|
├── payloads_host/ # Payload'ы только для host приложения
|
|||
|
|
└── payloads_app1/ # Payload'ы только для web_app1
|
|||
|
|
|
|||
|
|
apps/
|
|||
|
|
├── host_app/ # Flutter приложение с WebView
|
|||
|
|
└── web_app1/ # Flutter Web приложение
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Изоляция payload'ов
|
|||
|
|
|
|||
|
|
```dart
|
|||
|
|
// ✅ web_app1 может использовать:
|
|||
|
|
import 'package:payloads_shared/payloads_shared.dart';
|
|||
|
|
import 'package:payloads_app1/payloads_app1.dart';
|
|||
|
|
|
|||
|
|
// ❌ web_app1 НЕ может использовать:
|
|||
|
|
// import 'package:payloads_host/payloads_host.dart'; // Ошибка компиляции
|
|||
|
|
|
|||
|
|
// ✅ host_app может использовать все:
|
|||
|
|
import 'package:payloads_shared/payloads_shared.dart';
|
|||
|
|
import 'package:payloads_host/payloads_host.dart';
|
|||
|
|
import 'package:payloads_app1/payloads_app1.dart';
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 🔧 Ключевые компоненты
|
|||
|
|
|
|||
|
|
### 1. Bridge Core (`packages/bridge_core/`)
|
|||
|
|
|
|||
|
|
Базовые типы и сериализация для всей системы.
|
|||
|
|
|
|||
|
|
```dart
|
|||
|
|
// Базовый класс для всех payload'ов
|
|||
|
|
abstract class Payload {
|
|||
|
|
String get type;
|
|||
|
|
Map<String, dynamic> toJson();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Базовый класс для всех ответов
|
|||
|
|
abstract class PayloadResponse {
|
|||
|
|
String get type;
|
|||
|
|
Map<String, dynamic> toJson();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Базовый класс для обработчиков
|
|||
|
|
abstract class PayloadHandler<T extends Payload> {
|
|||
|
|
Future<PayloadResponse> handle(T payload);
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. Payloads Shared (`packages/payloads_shared/`)
|
|||
|
|
|
|||
|
|
Общие payload'ы, доступные всем приложениям.
|
|||
|
|
|
|||
|
|
```dart
|
|||
|
|
// Ping/Pong для проверки связи
|
|||
|
|
class PingPayload extends Payload {
|
|||
|
|
final String message;
|
|||
|
|
// ...
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
class PongResponse extends PayloadResponse {
|
|||
|
|
final String message;
|
|||
|
|
// ...
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Информация о пользователе
|
|||
|
|
class UserInfoPayload extends Payload {
|
|||
|
|
// ...
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
class UserInfoResponse extends PayloadResponse {
|
|||
|
|
final UserInfoData userInfo;
|
|||
|
|
// ...
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. Payloads Host (`packages/payloads_host/`)
|
|||
|
|
|
|||
|
|
Payload'ы только для host приложения.
|
|||
|
|
|
|||
|
|
```dart
|
|||
|
|
// Административные команды
|
|||
|
|
class AdminCommandPayload extends Payload {
|
|||
|
|
final String command;
|
|||
|
|
final Map<String, dynamic> parameters;
|
|||
|
|
// ...
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Нативные диалоги
|
|||
|
|
class NativeDialogPayload extends Payload {
|
|||
|
|
final String title;
|
|||
|
|
final String message;
|
|||
|
|
final String type;
|
|||
|
|
// ...
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4. Payloads App1 (`packages/payloads_app1/`)
|
|||
|
|
|
|||
|
|
Payload'ы только для web_app1.
|
|||
|
|
|
|||
|
|
```dart
|
|||
|
|
// Авторизация
|
|||
|
|
class LoginPayload extends Payload {
|
|||
|
|
final LoginData loginData;
|
|||
|
|
// ...
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
class LoginResponse extends PayloadResponse {
|
|||
|
|
final bool success;
|
|||
|
|
final String message;
|
|||
|
|
// ...
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Quiz система
|
|||
|
|
class QuizPayload extends Payload {
|
|||
|
|
final QuizResults results;
|
|||
|
|
// ...
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
class QuizResponse extends PayloadResponse {
|
|||
|
|
final bool saved;
|
|||
|
|
final String message;
|
|||
|
|
// ...
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 🔄 Поток данных
|
|||
|
|
|
|||
|
|
### 1. Web → Host коммуникация
|
|||
|
|
|
|||
|
|
```mermaid
|
|||
|
|
sequenceDiagram
|
|||
|
|
participant Web as web_app1
|
|||
|
|
participant JS as JavaScript Bridge
|
|||
|
|
participant WebView as Flutter WebView
|
|||
|
|
participant Host as host_app
|
|||
|
|
participant Handler as Payload Handler
|
|||
|
|
|
|||
|
|
Web->>JS: sendPayload(payload)
|
|||
|
|
JS->>WebView: callHandler('sendPayload', data)
|
|||
|
|
WebView->>Host: onMessageReceived(data)
|
|||
|
|
Host->>Handler: handle(payload)
|
|||
|
|
Handler->>Host: response
|
|||
|
|
Host->>WebView: sendResponse(response)
|
|||
|
|
WebView->>JS: callHandler('onResponse', response)
|
|||
|
|
JS->>Web: onResponse(response)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. JavaScript Bridge
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// Отправка payload'а в host
|
|||
|
|
window.flutter_inappwebview.callHandler('sendPayload', {
|
|||
|
|
type: 'ping',
|
|||
|
|
data: { message: 'Hello from Web!' }
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// Получение ответа от host
|
|||
|
|
window.flutter_inappwebview.callHandler('onResponse', function(response) {
|
|||
|
|
console.log('Response from host:', response);
|
|||
|
|
});
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. Host обработка
|
|||
|
|
|
|||
|
|
```dart
|
|||
|
|
class BridgeWebViewController {
|
|||
|
|
// Регистрация обработчиков
|
|||
|
|
void registerHandlers() {
|
|||
|
|
_bridge.registerHandler<PingPayload>(PingHandler());
|
|||
|
|
_bridge.registerHandler<UserInfoPayload>(UserInfoHandler());
|
|||
|
|
// ...
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Обработка входящих сообщений
|
|||
|
|
void onMessageReceived(Map<String, dynamic> data) {
|
|||
|
|
final payload = PayloadFactory.create(data);
|
|||
|
|
final response = _bridge.handle(payload);
|
|||
|
|
sendResponse(response);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 🏗️ Архитектура приложений
|
|||
|
|
|
|||
|
|
### Host App (`apps/host_app/`)
|
|||
|
|
|
|||
|
|
```dart
|
|||
|
|
// Структура файлов
|
|||
|
|
lib/
|
|||
|
|
├── src/
|
|||
|
|
│ ├── bridge_webview_controller.dart # Управление WebView и bridge
|
|||
|
|
│ ├── bridge_webview.dart # Flutter виджет WebView
|
|||
|
|
│ └── handlers/ # Обработчики payload'ов
|
|||
|
|
│ ├── payload_handler.dart # Базовый обработчик
|
|||
|
|
│ ├── ping_handler.dart # Ping/Pong
|
|||
|
|
│ ├── user_info_handler.dart # User info
|
|||
|
|
│ ├── admin_command_handler.dart # Admin commands
|
|||
|
|
│ ├── native_dialog_handler.dart # Native dialogs
|
|||
|
|
│ ├── login_handler.dart # Login
|
|||
|
|
│ └── quiz_handler.dart # Quiz
|
|||
|
|
└── main.dart # Точка входа
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Web App1 (`apps/web_app1/`)
|
|||
|
|
|
|||
|
|
```dart
|
|||
|
|
// Структура файлов
|
|||
|
|
lib/
|
|||
|
|
├── src/
|
|||
|
|
│ ├── web_bridge.dart # Управление связью с host
|
|||
|
|
│ ├── payload_handlers.dart # Обработчики ответов
|
|||
|
|
│ └── main.dart # Точка входа
|
|||
|
|
web/
|
|||
|
|
├── index.html # HTML страница
|
|||
|
|
└── bridge.js # JavaScript bridge
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 🔒 Безопасность
|
|||
|
|
|
|||
|
|
### 1. Изоляция payload'ов
|
|||
|
|
- Web приложения не могут использовать host payload'ы
|
|||
|
|
- Компилятор проверяет доступ к пакетам
|
|||
|
|
- Архитектура предотвращает утечки данных
|
|||
|
|
|
|||
|
|
### 2. Валидация данных
|
|||
|
|
- Все payload'ы валидируются при создании
|
|||
|
|
- Типобезопасность на уровне компилятора
|
|||
|
|
- Проверка структуры данных
|
|||
|
|
|
|||
|
|
### 3. Обработка ошибок
|
|||
|
|
- Graceful handling ошибок
|
|||
|
|
- Логирование для отладки
|
|||
|
|
- Fallback механизмы
|
|||
|
|
|
|||
|
|
## 📈 Производительность
|
|||
|
|
|
|||
|
|
### 1. Оптимизации
|
|||
|
|
- Минимальные overhead для bridge коммуникации
|
|||
|
|
- Эффективная сериализация JSON
|
|||
|
|
- Кэширование обработчиков
|
|||
|
|
|
|||
|
|
### 2. Мониторинг
|
|||
|
|
- Логирование времени выполнения
|
|||
|
|
- Метрики производительности
|
|||
|
|
- Отладка медленных операций
|
|||
|
|
|
|||
|
|
## 🔧 Расширяемость
|
|||
|
|
|
|||
|
|
### 1. Добавление новых payload'ов
|
|||
|
|
```dart
|
|||
|
|
// 1. Создать новый payload в соответствующем пакете
|
|||
|
|
class NewPayload extends Payload {
|
|||
|
|
final String data;
|
|||
|
|
// ...
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 2. Создать обработчик
|
|||
|
|
class NewPayloadHandler extends PayloadHandler<NewPayload> {
|
|||
|
|
@override
|
|||
|
|
Future<PayloadResponse> handle(NewPayload payload) async {
|
|||
|
|
// Логика обработки
|
|||
|
|
return NewResponse();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 3. Зарегистрировать обработчик
|
|||
|
|
_bridge.registerHandler<NewPayload>(NewPayloadHandler());
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. Добавление новых приложений
|
|||
|
|
- Создать новый пакет payload'ов
|
|||
|
|
- Создать Flutter Web приложение
|
|||
|
|
- Настроить изоляцию payload'ов
|
|||
|
|
- Добавить в host_app поддержку
|
|||
|
|
|
|||
|
|
## 🧪 Тестирование
|
|||
|
|
|
|||
|
|
### 1. Unit тесты
|
|||
|
|
- Тестирование всех payload'ов
|
|||
|
|
- Тестирование обработчиков
|
|||
|
|
- Тестирование сериализации
|
|||
|
|
|
|||
|
|
### 2. Integration тесты
|
|||
|
|
- Тестирование полного цикла коммуникации
|
|||
|
|
- Тестирование изоляции payload'ов
|
|||
|
|
- Тестирование JavaScript bridge
|
|||
|
|
|
|||
|
|
### 3. End-to-end тесты
|
|||
|
|
- Тестирование реальных сценариев
|
|||
|
|
- Тестирование производительности
|
|||
|
|
- Тестирование стабильности
|
|||
|
|
|
|||
|
|
## 📚 Документация
|
|||
|
|
|
|||
|
|
### 1. API документация
|
|||
|
|
- Описание всех payload'ов
|
|||
|
|
- Примеры использования
|
|||
|
|
- Best practices
|
|||
|
|
|
|||
|
|
### 2. Руководства
|
|||
|
|
- Быстрый старт
|
|||
|
|
- Интеграция в существующий проект
|
|||
|
|
- Troubleshooting
|
|||
|
|
|
|||
|
|
### 3. Примеры
|
|||
|
|
- Базовые примеры
|
|||
|
|
- Продвинутые сценарии
|
|||
|
|
- Реальные use cases
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🎯 Заключение
|
|||
|
|
|
|||
|
|
Архитектура Flutter WebView Bridge обеспечивает:
|
|||
|
|
- ✅ Безопасную коммуникацию между приложениями
|
|||
|
|
- ✅ Типобезопасность на уровне компилятора
|
|||
|
|
- ✅ Изоляцию payload'ов для безопасности
|
|||
|
|
- ✅ Простоту расширения и поддержки
|
|||
|
|
- ✅ Высокую производительность
|
|||
|
|
- ✅ Полное покрытие тестами
|
|||
|
|
|
|||
|
|
Система готова для использования в production проектах.
|