优化配置,修复 demo bug
1,network 框架完善 2,websocket 机制完善 3,设计文档整理到架构文档 4,脚本,配置完善
This commit is contained in:
@@ -13,6 +13,9 @@ class ApiError with _$ApiError implements Exception {
|
||||
required int code,
|
||||
required String message,
|
||||
}) = _ApiError;
|
||||
|
||||
/// 请求被 CancelToken 取消
|
||||
const factory ApiError.cancelled() = _Cancelled;
|
||||
const factory ApiError.unknown(String? message) = _Unknown;
|
||||
}
|
||||
|
||||
@@ -25,7 +28,8 @@ extension ApiErrorExtension on ApiError {
|
||||
networkError: (message) => 'Network error: $message',
|
||||
decodingError: (message) => 'Decoding error: $message',
|
||||
apiError: (code, message) => message,
|
||||
cancelled: () => 'Request cancelled',
|
||||
unknown: (message) => message ?? 'Unknown error',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,4 +8,13 @@ enum ApiRequestType {
|
||||
|
||||
/// 文件上传(multipart,不序列化 parameters)
|
||||
upload,
|
||||
|
||||
/// 流式请求(SSE / chunked)
|
||||
///
|
||||
/// SDK 内部自动切换 `ResponseType.plain`,Dio 返回原始文本。
|
||||
/// 业务 Request 类 override `decodeResponse` 处理 SSE 解析。
|
||||
stream,
|
||||
|
||||
/// 文件下载(带进度回调,支持断点续传)
|
||||
download,
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/// HTTP 请求加密结果
|
||||
///
|
||||
/// 加密回调返回此对象,[EncryptionInterceptor] 根据非 null 字段覆盖原始请求。
|
||||
/// 未设置的字段保持原值不变。
|
||||
///
|
||||
/// 设计依据:HTTP 加密模式下,加密后需要同时修改:
|
||||
/// - 路径(原文 path 加密为 hex 编码)
|
||||
/// - 请求体(JSON body 加密为 base64 字符串,不再是 Map)
|
||||
/// - Headers(添加 X-Token、X-Signature、secret-key 等加密 header)
|
||||
/// - Content-Type(JSON → text/plain)
|
||||
///
|
||||
/// ```dart
|
||||
/// // 加密回调返回示例
|
||||
/// EncryptedRequest(
|
||||
/// path: '/api/${hexEncode(encrypt(originalPath))}',
|
||||
/// body: base64Encode(encrypt(jsonBody)),
|
||||
/// headers: {
|
||||
/// 'X-Token': encryptedToken,
|
||||
/// 'X-Signature': signature,
|
||||
/// 'secret-key': clientPublicKey,
|
||||
/// },
|
||||
/// contentType: 'text/plain',
|
||||
/// )
|
||||
/// ```
|
||||
class EncryptedRequest {
|
||||
/// 加密后的路径
|
||||
///
|
||||
/// null 表示不修改路径。
|
||||
/// 如需加密,拦截器会用此值替换 `RequestOptions.path`。
|
||||
final String? path;
|
||||
|
||||
/// 加密后的请求体
|
||||
///
|
||||
/// null 表示不修改 body。
|
||||
/// 类型不限于 Map — 加密后通常是 base64 字符串或 bytes。
|
||||
final Object? body;
|
||||
|
||||
/// 需要添加或覆盖的 headers
|
||||
///
|
||||
/// null 表示不修改 headers。
|
||||
/// 拦截器会将这些 header 合并到请求中(覆盖同名 header)。
|
||||
final Map<String, String>? headers;
|
||||
|
||||
/// 覆盖 Content-Type
|
||||
///
|
||||
/// null 表示不修改。加密后通常是 `text/plain`(body 已是字符串,非 JSON)。
|
||||
final String? contentType;
|
||||
|
||||
const EncryptedRequest({
|
||||
this.path,
|
||||
this.body,
|
||||
this.headers,
|
||||
this.contentType,
|
||||
});
|
||||
}
|
||||
@@ -1,49 +1,45 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:networks_sdk/src/domain/entities/socket_connection_state.dart';
|
||||
import 'package:networks_sdk/src/domain/entities/socket_error.dart';
|
||||
import 'package:networks_sdk/src/presentation/wiring/socket_config.dart';
|
||||
|
||||
/// Messaging Repository Interface (Domain)
|
||||
/// Messaging Repository 接口
|
||||
abstract class NetworksMessagingRepository {
|
||||
/// Initialize with config
|
||||
void initialize(SocketConfig config);
|
||||
|
||||
/// Connect to messaging server
|
||||
Future<bool> connect(String url, {String? token});
|
||||
|
||||
/// Disconnect from server
|
||||
Future<void> disconnect();
|
||||
|
||||
/// Check if connected
|
||||
bool get isConnected;
|
||||
|
||||
/// Current connection state
|
||||
SocketConnectionState get connectionState;
|
||||
|
||||
/// Send a JSON message
|
||||
/// Token 热更新(不断连)
|
||||
void updateToken(String token);
|
||||
|
||||
Future<bool> send(Map<String, dynamic> message);
|
||||
|
||||
/// Send a raw string message
|
||||
Future<bool> sendString(String message);
|
||||
|
||||
/// Stream of incoming parsed JSON messages
|
||||
/// 发送二进制数据
|
||||
Future<bool> sendBytes(List<int> bytes);
|
||||
|
||||
Stream<Map<String, dynamic>> get messageStream;
|
||||
|
||||
/// Stream of raw string messages
|
||||
Stream<String> get rawMessageStream;
|
||||
|
||||
/// Stream of connection state changes
|
||||
/// 二进制消息流
|
||||
Stream<Uint8List> get binaryMessageStream;
|
||||
|
||||
Stream<SocketConnectionState> get connectionStateStream;
|
||||
|
||||
/// Stream of errors
|
||||
Stream<SocketError> get errorStream;
|
||||
|
||||
/// Called when app enters foreground
|
||||
void onEnterForeground();
|
||||
|
||||
/// Called when app enters background
|
||||
void onEnterBackground();
|
||||
|
||||
/// Dispose all resources
|
||||
Future<void> dispose();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,32 @@
|
||||
// Repository Interface(Domain)
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:networks_sdk/src/data/dto/api_requestable.dart';
|
||||
import 'package:networks_sdk/src/presentation/wiring/api_config.dart';
|
||||
import 'package:networks_sdk/src/presentation/wiring/network_callbacks.dart';
|
||||
|
||||
/// 网络层 Repository 接口
|
||||
///
|
||||
/// 定义两种请求入口:
|
||||
/// - [executeRequest] — 统一请求入口(标准 / Upload / 流式)
|
||||
/// - [executeDownload] — 带进度的文件下载(支持断点续传)
|
||||
abstract class NetworksSdkRepository {
|
||||
Future<String?> platformVersion();
|
||||
|
||||
void initialize(ApiConfig apiConfig);
|
||||
|
||||
Future<T?> executeRequest<T>(ApiRequestable<T> request);
|
||||
}
|
||||
Future<T?> executeRequest<T>(
|
||||
ApiRequestable<T> request, {
|
||||
CancelToken? cancelToken,
|
||||
});
|
||||
|
||||
/// 文件下载(支持进度回调和断点续传)
|
||||
Future<void> executeDownload({
|
||||
required String url,
|
||||
required String savePath,
|
||||
OnDownloadProgress? onProgress,
|
||||
CancelToken? cancelToken,
|
||||
bool resume = false,
|
||||
Map<String, String>? headers,
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user