|
|
# API 文档
|
|
|
|
|
|
本文档详细介绍 Flash Send 的 Tauri 命令 API 和事件系统。
|
|
|
|
|
|
## Tauri 命令
|
|
|
|
|
|
所有命令通过 `@tauri-apps/api/core` 的 `invoke` 函数调用。
|
|
|
|
|
|
### 设备发现
|
|
|
|
|
|
#### start_discovery
|
|
|
|
|
|
启动设备发现服务,开始广播本机信息并监听其他设备。
|
|
|
|
|
|
```typescript
|
|
|
invoke('start_discovery')
|
|
|
```
|
|
|
|
|
|
**返回**: `Promise<void>`
|
|
|
|
|
|
---
|
|
|
|
|
|
#### stop_discovery
|
|
|
|
|
|
停止设备发现服务。
|
|
|
|
|
|
```typescript
|
|
|
invoke('stop_discovery')
|
|
|
```
|
|
|
|
|
|
**返回**: `Promise<void>`
|
|
|
|
|
|
---
|
|
|
|
|
|
#### get_online_devices
|
|
|
|
|
|
获取当前在线的设备列表。
|
|
|
|
|
|
```typescript
|
|
|
invoke<DeviceInfo[]>('get_online_devices')
|
|
|
```
|
|
|
|
|
|
**返回**: `Promise<DeviceInfo[]>`
|
|
|
|
|
|
```typescript
|
|
|
interface DeviceInfo {
|
|
|
deviceId: string // 设备唯一标识
|
|
|
deviceName: string // 设备名称
|
|
|
ip: string // IP 地址
|
|
|
wsPort: number // WebSocket 端口
|
|
|
httpPort: number // HTTP 端口
|
|
|
lastSeen: number // 最后在线时间戳
|
|
|
}
|
|
|
```
|
|
|
|
|
|
---
|
|
|
|
|
|
#### get_local_device
|
|
|
|
|
|
获取本机设备信息。
|
|
|
|
|
|
```typescript
|
|
|
invoke<DeviceInfo>('get_local_device')
|
|
|
```
|
|
|
|
|
|
**返回**: `Promise<DeviceInfo>`
|
|
|
|
|
|
---
|
|
|
|
|
|
### 聊天通信
|
|
|
|
|
|
#### start_ws_server
|
|
|
|
|
|
启动 WebSocket 服务端,接收其他设备的连接。
|
|
|
|
|
|
```typescript
|
|
|
invoke('start_ws_server')
|
|
|
```
|
|
|
|
|
|
**返回**: `Promise<void>`
|
|
|
|
|
|
---
|
|
|
|
|
|
#### connect_to_device
|
|
|
|
|
|
连接到指定设备的 WebSocket 服务。
|
|
|
|
|
|
```typescript
|
|
|
invoke('connect_to_device', { deviceId: string })
|
|
|
```
|
|
|
|
|
|
**参数**:
|
|
|
| 参数 | 类型 | 说明 |
|
|
|
|------|------|------|
|
|
|
| deviceId | string | 目标设备 ID |
|
|
|
|
|
|
**返回**: `Promise<void>`
|
|
|
|
|
|
---
|
|
|
|
|
|
#### send_chat_message
|
|
|
|
|
|
发送聊天消息。
|
|
|
|
|
|
```typescript
|
|
|
invoke<ChatMessage>('send_chat_message', {
|
|
|
deviceId: string,
|
|
|
content: string,
|
|
|
messageType?: string
|
|
|
})
|
|
|
```
|
|
|
|
|
|
**参数**:
|
|
|
| 参数 | 类型 | 默认值 | 说明 |
|
|
|
|------|------|--------|------|
|
|
|
| deviceId | string | - | 目标设备 ID |
|
|
|
| content | string | - | 消息内容 |
|
|
|
| messageType | string | 'text' | 消息类型:text/image/file |
|
|
|
|
|
|
**返回**: `Promise<ChatMessage>`
|
|
|
|
|
|
```typescript
|
|
|
interface ChatMessage {
|
|
|
id: string
|
|
|
fromDevice: string
|
|
|
toDevice: string
|
|
|
content: string
|
|
|
messageType: 'text' | 'image' | 'file' | 'system'
|
|
|
timestamp: number
|
|
|
isRead: boolean
|
|
|
}
|
|
|
```
|
|
|
|
|
|
---
|
|
|
|
|
|
#### get_chat_history
|
|
|
|
|
|
获取与指定设备的聊天历史。
|
|
|
|
|
|
```typescript
|
|
|
invoke<ChatMessage[]>('get_chat_history', {
|
|
|
deviceId: string,
|
|
|
limit?: number,
|
|
|
offset?: number
|
|
|
})
|
|
|
```
|
|
|
|
|
|
**参数**:
|
|
|
| 参数 | 类型 | 默认值 | 说明 |
|
|
|
|------|------|--------|------|
|
|
|
| deviceId | string | - | 目标设备 ID |
|
|
|
| limit | number | 50 | 返回条数限制 |
|
|
|
| offset | number | 0 | 偏移量 |
|
|
|
|
|
|
**返回**: `Promise<ChatMessage[]>`
|
|
|
|
|
|
---
|
|
|
|
|
|
#### delete_chat_history
|
|
|
|
|
|
删除与指定设备的聊天历史。
|
|
|
|
|
|
```typescript
|
|
|
invoke('delete_chat_history', { deviceId: string })
|
|
|
```
|
|
|
|
|
|
**参数**:
|
|
|
| 参数 | 类型 | 说明 |
|
|
|
|------|------|------|
|
|
|
| deviceId | string | 目标设备 ID |
|
|
|
|
|
|
**返回**: `Promise<void>`
|
|
|
|
|
|
---
|
|
|
|
|
|
### 文件传输
|
|
|
|
|
|
#### start_http_server
|
|
|
|
|
|
启动 HTTPS 文件服务,接收文件上传。
|
|
|
|
|
|
```typescript
|
|
|
invoke('start_http_server')
|
|
|
```
|
|
|
|
|
|
**返回**: `Promise<void>`
|
|
|
|
|
|
---
|
|
|
|
|
|
#### select_file
|
|
|
|
|
|
打开文件选择对话框。
|
|
|
|
|
|
```typescript
|
|
|
invoke<FileMetadata | null>('select_file')
|
|
|
```
|
|
|
|
|
|
**返回**: `Promise<FileMetadata | null>`
|
|
|
|
|
|
```typescript
|
|
|
interface FileMetadata {
|
|
|
name: string // 文件名
|
|
|
path: string // 文件完整路径
|
|
|
size: number // 文件大小(字节)
|
|
|
mimeType?: string // MIME 类型
|
|
|
}
|
|
|
```
|
|
|
|
|
|
---
|
|
|
|
|
|
#### send_file
|
|
|
|
|
|
发送文件到指定设备。
|
|
|
|
|
|
```typescript
|
|
|
invoke<FileTransfer>('send_file', {
|
|
|
deviceId: string,
|
|
|
fileId: string,
|
|
|
filePath: string
|
|
|
})
|
|
|
```
|
|
|
|
|
|
**参数**:
|
|
|
| 参数 | 类型 | 说明 |
|
|
|
|------|------|------|
|
|
|
| deviceId | string | 目标设备 ID |
|
|
|
| fileId | string | 文件传输 ID(UUID) |
|
|
|
| filePath | string | 本地文件路径 |
|
|
|
|
|
|
**返回**: `Promise<FileTransfer>`
|
|
|
|
|
|
```typescript
|
|
|
interface FileTransfer {
|
|
|
fileId: string
|
|
|
name: string
|
|
|
size: number
|
|
|
progress: number // 0.0 - 1.0
|
|
|
status: TransferStatus
|
|
|
mimeType?: string
|
|
|
fromDevice: string
|
|
|
toDevice: string
|
|
|
localPath?: string
|
|
|
createdAt: number
|
|
|
completedAt?: number
|
|
|
transferredBytes: number
|
|
|
}
|
|
|
|
|
|
type TransferStatus = 'pending' | 'transferring' | 'completed' | 'failed' | 'cancelled'
|
|
|
```
|
|
|
|
|
|
---
|
|
|
|
|
|
#### cancel_transfer
|
|
|
|
|
|
取消文件传输。
|
|
|
|
|
|
```typescript
|
|
|
invoke('cancel_transfer', { fileId: string })
|
|
|
```
|
|
|
|
|
|
**参数**:
|
|
|
| 参数 | 类型 | 说明 |
|
|
|
|------|------|------|
|
|
|
| fileId | string | 传输 ID |
|
|
|
|
|
|
**返回**: `Promise<void>`
|
|
|
|
|
|
---
|
|
|
|
|
|
#### get_transfer_history
|
|
|
|
|
|
获取与指定设备的文件传输历史。
|
|
|
|
|
|
```typescript
|
|
|
invoke<FileTransfer[]>('get_transfer_history', {
|
|
|
deviceId: string,
|
|
|
limit?: number
|
|
|
})
|
|
|
```
|
|
|
|
|
|
**参数**:
|
|
|
| 参数 | 类型 | 默认值 | 说明 |
|
|
|
|------|------|--------|------|
|
|
|
| deviceId | string | - | 目标设备 ID |
|
|
|
| limit | number | 50 | 返回条数限制 |
|
|
|
|
|
|
**返回**: `Promise<FileTransfer[]>`
|
|
|
|
|
|
---
|
|
|
|
|
|
#### open_file_location
|
|
|
|
|
|
在系统文件管理器中打开文件所在位置。
|
|
|
|
|
|
```typescript
|
|
|
invoke('open_file_location', { path: string })
|
|
|
```
|
|
|
|
|
|
**参数**:
|
|
|
| 参数 | 类型 | 说明 |
|
|
|
|------|------|------|
|
|
|
| path | string | 文件路径 |
|
|
|
|
|
|
**返回**: `Promise<void>`
|
|
|
|
|
|
**平台行为**:
|
|
|
- **Windows**: `explorer /select, <path>`
|
|
|
- **macOS**: `open -R <path>`
|
|
|
- **Linux**: `xdg-open <dir>`
|
|
|
|
|
|
---
|
|
|
|
|
|
### 配置管理
|
|
|
|
|
|
#### get_app_config
|
|
|
|
|
|
获取应用配置。
|
|
|
|
|
|
```typescript
|
|
|
invoke<AppConfig>('get_app_config')
|
|
|
```
|
|
|
|
|
|
**返回**: `Promise<AppConfig>`
|
|
|
|
|
|
```typescript
|
|
|
interface AppConfig {
|
|
|
deviceId: string // 本机设备 ID
|
|
|
deviceName: string // 设备名称
|
|
|
downloadDir: string // 下载目录
|
|
|
wsPort: number // WebSocket 端口
|
|
|
httpPort: number // HTTP 端口
|
|
|
}
|
|
|
```
|
|
|
|
|
|
---
|
|
|
|
|
|
#### update_device_name
|
|
|
|
|
|
更新设备名称。
|
|
|
|
|
|
```typescript
|
|
|
invoke('update_device_name', { name: string })
|
|
|
```
|
|
|
|
|
|
**参数**:
|
|
|
| 参数 | 类型 | 说明 |
|
|
|
|------|------|------|
|
|
|
| name | string | 新的设备名称 |
|
|
|
|
|
|
**返回**: `Promise<void>`
|
|
|
|
|
|
---
|
|
|
|
|
|
#### update_download_dir
|
|
|
|
|
|
更新文件下载目录。
|
|
|
|
|
|
```typescript
|
|
|
invoke('update_download_dir', { path: string })
|
|
|
```
|
|
|
|
|
|
**参数**:
|
|
|
| 参数 | 类型 | 说明 |
|
|
|
|------|------|------|
|
|
|
| path | string | 新的下载目录路径 |
|
|
|
|
|
|
**返回**: `Promise<void>`
|
|
|
|
|
|
---
|
|
|
|
|
|
## 事件系统
|
|
|
|
|
|
通过 `@tauri-apps/api/event` 的 `listen` 函数监听后端事件。
|
|
|
|
|
|
### device:found
|
|
|
|
|
|
发现新设备时触发。
|
|
|
|
|
|
```typescript
|
|
|
import { listen } from '@tauri-apps/api/event'
|
|
|
|
|
|
listen<DeviceInfo>('device:found', (event) => {
|
|
|
console.log('发现设备:', event.payload)
|
|
|
})
|
|
|
```
|
|
|
|
|
|
**Payload**: `DeviceInfo`
|
|
|
|
|
|
---
|
|
|
|
|
|
### device:lost
|
|
|
|
|
|
设备离线时触发。
|
|
|
|
|
|
```typescript
|
|
|
listen<string>('device:lost', (event) => {
|
|
|
console.log('设备离线:', event.payload) // device_id
|
|
|
})
|
|
|
```
|
|
|
|
|
|
**Payload**: `string` (device_id)
|
|
|
|
|
|
---
|
|
|
|
|
|
### chat:message
|
|
|
|
|
|
收到聊天消息时触发。
|
|
|
|
|
|
```typescript
|
|
|
listen<ChatMessage>('chat:message', (event) => {
|
|
|
console.log('收到消息:', event.payload)
|
|
|
})
|
|
|
```
|
|
|
|
|
|
**Payload**: `ChatMessage`
|
|
|
|
|
|
---
|
|
|
|
|
|
### file:progress
|
|
|
|
|
|
文件传输进度更新时触发。
|
|
|
|
|
|
```typescript
|
|
|
listen<TransferProgressEvent>('file:progress', (event) => {
|
|
|
console.log('传输进度:', event.payload)
|
|
|
})
|
|
|
```
|
|
|
|
|
|
**Payload**: `TransferProgressEvent`
|
|
|
|
|
|
```typescript
|
|
|
interface TransferProgressEvent {
|
|
|
fileId: string // 传输 ID
|
|
|
progress: number // 进度 0.0 - 1.0
|
|
|
transferredBytes: number // 已传输字节数
|
|
|
totalBytes: number // 总字节数
|
|
|
status: TransferStatus // 传输状态
|
|
|
fileName?: string // 文件名(接收方)
|
|
|
localPath?: string // 本地路径(接收方)
|
|
|
}
|
|
|
```
|
|
|
|
|
|
---
|
|
|
|
|
|
## 错误处理
|
|
|
|
|
|
所有命令在出错时会抛出 `CommandError`:
|
|
|
|
|
|
```typescript
|
|
|
interface CommandError {
|
|
|
code: string // 错误代码
|
|
|
message: string // 错误信息
|
|
|
}
|
|
|
```
|
|
|
|
|
|
**常见错误代码**:
|
|
|
|
|
|
| 代码 | 说明 |
|
|
|
|------|------|
|
|
|
| `DB_ERROR` | 数据库操作错误 |
|
|
|
| `IO_ERROR` | 文件 IO 错误 |
|
|
|
| `WS_ERROR` | WebSocket 错误 |
|
|
|
| `DEVICE_NOT_FOUND` | 设备不存在 |
|
|
|
| `NOT_CONNECTED` | 未建立连接 |
|
|
|
| `TRANSFER_ERROR` | 传输错误 |
|
|
|
|
|
|
**使用示例**:
|
|
|
|
|
|
```typescript
|
|
|
try {
|
|
|
await invoke('send_chat_message', { deviceId, content })
|
|
|
} catch (error) {
|
|
|
const err = error as CommandError
|
|
|
if (err.code === 'NOT_CONNECTED') {
|
|
|
// 尝试重新连接
|
|
|
await invoke('connect_to_device', { deviceId })
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
---
|
|
|
|
|
|
## 完整示例
|
|
|
|
|
|
### 设备发现与聊天
|
|
|
|
|
|
```typescript
|
|
|
import { invoke } from '@tauri-apps/api/core'
|
|
|
import { listen } from '@tauri-apps/api/event'
|
|
|
|
|
|
// 1. 监听设备发现事件
|
|
|
const unlistenDevice = await listen<DeviceInfo>('device:found', (event) => {
|
|
|
console.log('发现设备:', event.payload.deviceName)
|
|
|
})
|
|
|
|
|
|
// 2. 监听消息事件
|
|
|
const unlistenMessage = await listen<ChatMessage>('chat:message', (event) => {
|
|
|
console.log('收到消息:', event.payload.content)
|
|
|
})
|
|
|
|
|
|
// 3. 启动服务
|
|
|
await invoke('start_ws_server')
|
|
|
await invoke('start_discovery')
|
|
|
|
|
|
// 4. 获取在线设备
|
|
|
const devices = await invoke<DeviceInfo[]>('get_online_devices')
|
|
|
|
|
|
// 5. 连接设备并发送消息
|
|
|
if (devices.length > 0) {
|
|
|
const device = devices[0]
|
|
|
await invoke('connect_to_device', { deviceId: device.deviceId })
|
|
|
await invoke('send_chat_message', {
|
|
|
deviceId: device.deviceId,
|
|
|
content: 'Hello!'
|
|
|
})
|
|
|
}
|
|
|
|
|
|
// 清理
|
|
|
unlistenDevice()
|
|
|
unlistenMessage()
|
|
|
await invoke('stop_discovery')
|
|
|
```
|
|
|
|
|
|
### 文件传输
|
|
|
|
|
|
```typescript
|
|
|
import { invoke } from '@tauri-apps/api/core'
|
|
|
import { listen } from '@tauri-apps/api/event'
|
|
|
|
|
|
// 1. 监听传输进度
|
|
|
const unlisten = await listen<TransferProgressEvent>('file:progress', (event) => {
|
|
|
const { fileId, progress, status } = event.payload
|
|
|
console.log(`${fileId}: ${(progress * 100).toFixed(1)}% - ${status}`)
|
|
|
})
|
|
|
|
|
|
// 2. 启动文件服务
|
|
|
await invoke('start_http_server')
|
|
|
|
|
|
// 3. 选择文件
|
|
|
const file = await invoke<FileMetadata | null>('select_file')
|
|
|
if (!file) return
|
|
|
|
|
|
// 4. 发送文件
|
|
|
const fileId = crypto.randomUUID()
|
|
|
const transfer = await invoke<FileTransfer>('send_file', {
|
|
|
deviceId: targetDeviceId,
|
|
|
fileId,
|
|
|
filePath: file.path
|
|
|
})
|
|
|
|
|
|
console.log('开始传输:', transfer.name)
|
|
|
|
|
|
// 清理
|
|
|
unlisten()
|
|
|
```
|