D: 删除通信桥接层及相关实现 (AppBridge, BaseBridge, BridgeFactory, CSharpBridge, IBridge, TauriBridge, WebMockBridge)

This commit is contained in:
jimmy committed 2025-05-10 16:20:09 +08:00
1 parent 71fb7e2db1
commit b14594ffb3
7 files changed
-385

No files matched your search

-66
View File
@@ -1,66 +0,0 @@
import IBridge from "./IBridge";
/**
* 业务层类型定义
*/
export interface UserInfo {
id: string;
name: string;
email?: string;
role: string;
permissions: string[];
}
export interface Notification {
id: string;
title: string;
message: string;
type: 'info' | 'warning' | 'error' | 'success';
timestamp: number;
}
export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
export interface LogPayload {
level: LogLevel;
message: string;
context?: Record<string, unknown>;
}
/**
* 业务功能层 - 提供更高级的通信功能
*/
export class AppBridge {
private bridge: IBridge;
constructor() {
this.bridge = BridgeFactory.create();
}
// 获取用户信息
async getUserInfo(): Promise<UserInfo> {
return this.bridge.send<UserInfo>('user.getInfo');
}
// 监听系统通知
onNotification(listener: (notification: Notification) => void): () => void {
return this.bridge.on<Notification>('system.notification', listener);
}
// 发送日志
async sendLog(payload: LogPayload): Promise<void> {
return this.bridge.send<void, LogPayload>('system.log', payload);
}
// 获取系统配置
async getConfig<T extends Record<string, unknown>>(key: string): Promise<T> {
return this.bridge.send<T, { key: string }>('system.getConfig', { key });
}
// 保存系统配置
async saveConfig<T extends Record<string, unknown>>(key: string, value: T): Promise<void> {
return this.bridge.send<void, { key: string; value: T }>('system.saveConfig', { key, value });
}
}
// 创建单例实例
export const appBridge = new AppBridge();
-88
View File
@@ -1,88 +0,0 @@
/**
* Time:2025/5/10 13:42 55
* Name:BaseBridge.ts
* Path:src/correspond
* ProjectName:ClientApp
* Author:charlatans
*
* Il n'ya qu'un héroïsme au monde :
* c'est de voir le monde tel qu'il est et de l'aimer.
*/
import type MessagePayload from "./IBridge"
import { IBridge } from '@/correspond/IBridge'
/**
* 平台适配层基类
*/
abstract class BaseBridge implements IBridge {
protected listeners: Map<string, Set<(data: unknown) => void>> = new Map();
abstract send<TResponse = void, TRequest extends MessagePayload = MessagePayload>(
channel: string,
data?: TRequest
): Promise<TResponse>;
on<TData extends MessagePayload = MessagePayload>(
channel: string,
listener: (data: TData) => void
): () => void {
if (!this.listeners.has(channel)) {
this.listeners.set(channel, new Set());
}
// TypeScript 不允许将具体类型的函数分配给更通用的类型,因此这里需要类型转换
const typedListener = listener as (data: unknown) => void;
this.listeners.get(channel)!.add(typedListener);
return () => this.removeListener(channel, listener);
}
once<TData extends MessagePayload = MessagePayload>(
channel: string,
listener: (data: TData) => void
): () => void {
// 创建一个一次性监听器
const onceListener = ((data: TData) => {
listener(data);
this.removeListener(channel, onceListener);
});
return this.on(channel, onceListener);
}
off(channel: string): void {
this.listeners.delete(channel);
}
removeListener<TData extends MessagePayload = MessagePayload>(
channel: string,
listener: (data: TData) => void
): void {
const channelListeners = this.listeners.get(channel);
if (channelListeners) {
// 需要类型转换以匹配存储的监听器类型
const typedListener = listener as (data: unknown) => void;
channelListeners.delete(typedListener);
if (channelListeners.size === 0) {
this.listeners.delete(channel);
}
}
}
protected dispatchEvent<TData extends MessagePayload = MessagePayload>(
channel: string,
data: TData
): void {
const listeners = this.listeners.get(channel);
if (listeners) {
listeners.forEach(listener => {
try {
listener(data);
} catch (error) {
console.error(`Error in listener for channel ${channel}:`, error);
}
});
}
}
}
-20
View File
@@ -1,20 +0,0 @@
import CSharpBridge from "./CSharpBridge";
import TauriBridge from "./TauriBridge";
/**
* 桥梁工厂 - 根据运行环境创建适当的桥梁实例
*/
export class BridgeFactory {
static create(): IBridge {
if (typeof window !== 'undefined') {
// 根据环境判断使用哪个桥接实现
if (window.csharpApp) {
return new CSharpBridge();
} else if (window.__TAURI__) {
return new TauriBridge();
}
}
// 默认返回一个Web模拟实现
return new WebMockBridge();
}
}
-44
View File
@@ -1,44 +0,0 @@
import BaseBridge from "./BaseBridge"
/**
* C#套壳浏览器的适配器
*/
class CSharpBridge extends BaseBridge {
constructor() {
super();
// 假设C#注入了window.csharpApp对象
if (typeof window !== 'undefined' && window.csharpApp) {
// 监听C#发来的消息
window.receiveCSharpMessage = (channel: string, dataJson: string) => {
try {
const data = JSON.parse(dataJson) as MessagePayload;
this.dispatchEvent(channel, data);
} catch (error) {
console.error('Failed to parse message from C#:', error);
}
};
}
}
async send<TResponse = void, TRequest extends MessagePayload = MessagePayload>(
channel: string,
data?: TRequest
): Promise<TResponse> {
if (typeof window === 'undefined' || !window.csharpApp) {
throw new BridgeError('CSharp bridge not available', 'BRIDGE_UNAVAILABLE');
}
try {
// 假设C#提供了sendToCSharp方法
const responseJson = window.csharpApp.sendToCSharp(
channel,
JSON.stringify(data || {})
);
return JSON.parse(responseJson) as TResponse;
} catch (error) {
if (error instanceof Error) {
throw new BridgeError(`Failed to send message to C#: ${error.message}`, 'SEND_FAILED');
}
throw new BridgeError('Unknown error when sending message to C#', 'UNKNOWN_ERROR');
}
}
}
-80
View File
@@ -1,80 +0,0 @@
/**
* Time:2025/5/10 13:31 41
* Name:IBridge.ts
* Path:src/correspond
* ProjectName:ClientApp
* Author:charlatans
*
* Il n'ya qu'un héroïsme au monde :
* c'est de voir le monde tel qu'il est et de l'aimer.
*/
/**
* 消息类型定义 - 用于类型安全的通信
*/
export type MessagePayload = Record<string, unknown>;
/**
* 核心接口层 - 定义与后端通信的基本能力
*/
export interface IBridge {
// 发送消息到后端
send<TResponse = void, TRequest extends MessagePayload = MessagePayload>(
channel: string,
data?: TRequest
): Promise<TResponse>;
// 监听后端消息
on<TData extends MessagePayload = MessagePayload>(
channel: string,
listener: (data: TData) => void
): () => void;
// 只监听一次后端消息
once<TData extends MessagePayload = MessagePayload>(
channel: string,
listener: (data: TData) => void
): () => void;
// 移除指定通道的所有监听器
off(channel: string): void;
// 移除特定监听器
removeListener<TData extends MessagePayload = MessagePayload>(
channel: string,
listener: (data: TData) => void
): void;
}
/**
* 定义Window扩展,用于与原生平台交互
*/
interface CSharpAppInterface {
sendToCSharp(channel: string, dataJson: string): string;
}
interface TauriInterface {
invoke<T>(cmd: string, args?: unknown): Promise<T>;
event: {
listen(event: string, handler: (event: { payload: unknown }) => void): Promise<() => void>;
once(event: string, handler: (event: { payload: unknown }) => void): Promise<void>;
unlisten(event: string): Promise<void>;
};
}
interface WindowWithNative extends Window {
csharpApp?: CSharpAppInterface;
receiveCSharpMessage?: (channel: string, dataJson: string) => void;
__TAURI__?: TauriInterface;
}
declare let window: WindowWithNative;
/**
* 异常类型定义
*/
export class BridgeError extends Error {
constructor(message: string, public readonly code?: string) {
super(message);
this.name = 'BridgeError';
}
}
-62
View File
@@ -1,62 +0,0 @@
import BaseBridge from "./BaseBridge";
/**
* Tauri适配器
*/
class TauriBridge extends BaseBridge {
constructor() {
super();
// Tauri初始化代码
if (typeof window !== 'undefined' && window.__TAURI__) {
// 设置Tauri事件监听
window.__TAURI__.event.listen('tauri://event', (event: { payload: unknown }) => {
const eventData = event.payload as { channel: string; payload: MessagePayload };
if (eventData.channel) {
this.dispatchEvent(eventData.channel, eventData.payload);
}
});
}
}
async send<TResponse = void, TRequest extends MessagePayload = MessagePayload>(
channel: string,
data?: TRequest
): Promise<TResponse> {
if (typeof window === 'undefined' || !window.__TAURI__) {
throw new BridgeError('Tauri bridge not available', 'BRIDGE_UNAVAILABLE');
}
try {
// 使用Tauri的invoke函数
return await window.__TAURI__.invoke<TResponse>(channel, data || {});
} catch (error) {
if (error instanceof Error) {
throw new BridgeError(`Failed to invoke Tauri command: ${error.message}`, 'INVOKE_FAILED');
}
throw new BridgeError('Unknown error when invoking Tauri command', 'UNKNOWN_ERROR');
}
}
override on<TData extends MessagePayload = MessagePayload>(
channel: string,
listener: (data: TData) => void
): () => void {
const unsubscribe = super.on(channel, listener);
// 向Tauri注册事件监听
if (typeof window !== 'undefined' && window.__TAURI__) {
window.__TAURI__.event.listen(channel, (event: { payload: unknown }) => {
listener(event.payload as TData);
}).catch(console.error);
}
return unsubscribe;
}
override off(channel: string): void {
super.off(channel);
// Tauri的事件注销需要特殊处理
if (typeof window !== 'undefined' && window.__TAURI__) {
window.__TAURI__.event.unlisten(channel).catch(console.error);
}
}
}
-25
View File
@@ -1,25 +0,0 @@
import BaseBridge from "./BaseBridge";
/**
* Web环境的模拟实现 - 用于开发调试
*/
class WebMockBridge extends BaseBridge {
async send<TResponse = void, TRequest extends MessagePayload = MessagePayload>(
channel: string,
data?: TRequest
): Promise<TResponse> {
console.log(`[WebMock] Send to channel ${channel}:`, data);
// 模拟异步响应
return new Promise<TResponse>(resolve => {
setTimeout(() => {
// 默认的模拟响应
const mockResponse = { success: true, mock: true } as unknown as TResponse;
resolve(mockResponse);
}, 100);
});
}
// 用于测试 - 模拟后端发送消息
mockReceive<TData extends MessagePayload = MessagePayload>(channel: string, data: TData): void {
this.dispatchEvent(channel, data);
}
}