更新时间:2025-12-16 07:22:06下载pdf
扫地机的 P2P 能力是依托于 IPC 的 P2P 和文件传输实现的,除了基础的涂鸦 SDK,还需要额外依赖这两个库,即可直接使用。
SDK 包:
@thingsmart/thingp2pfiletranssdk - P2P 文件传输核心库@thingsmart/ipcsdk - IPC功能库平台: HarmonyOS (ArkTS)
// IPC SDK 管理器
import { ThingIPCSdk } from '@thingsmart/ipcsdk'
// P2P 文件传输核心
import {
ThingP2pFileTransManager, // 文件传输管理器(静态类)
ThingP2pFileTransInterface, // 文件传输接口
ThingP2pFileTransListener // 文件传输监听器
} from '@thingsmart/thingp2pfiletranssdk'
功能描述
获取 P2P 管理实例,用于管理 P2P 连接的生命周期。这是一个单例模式的静态方法。
函数签名
static getP2P(): IThingP2P
参数说明
无
返回值
| 类型 | 说明 |
|---|---|
| IThingP2P | P2P 管理实例,包含初始化、连接、断开等方法 |
注意事项
使用示例
const p2pManager = ThingIPCSdk.getP2P()
功能描述
初始化 P2P SDK,这是使用 SDK 所有功能前的必要步骤。初始化会配置 SDK 运行环境、注册必要的服务和组件。
函数签名
initP2P(userId: string): number
参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| userId | string | 是 | 用户 ID,用于标识当前用户 |
返回值
| 类型 | 说明 |
|---|---|
| number | 调用结果:0=成功,其他值=失败 |
注意事项
使用示例
const result = ThingIPCSdk.getP2P().initP2P('user_12345')
if (result === 0) {
L.i('P2PDemo', 'SDK 初始化成功')
} else {
L.e('P2PDemo', `SDK 初始化失败: ${result}`)
}
功能描述
连接指定的设备,建立 P2P 会话。连接成功后会通过回调返回 sessionId(handle),用于后续文件传输操作。
函数签名
connectWithDevId(remoteId: string, lanMode: number, timeout: number, callback: IThingP2PCallback): string
参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| remoteId | string | 是 | 设备 ID(远程设备标识符) |
| lanMode | number | 是 | 连接模式:0=互联网模式,1=局域网模式 |
| timeout | number | 是 | 超时时间(毫秒),建议不低于 10000ms |
| callback | IThingP2PCallback | 是 | P2P 回调接口 |
IThingP2PCallback 接口定义
interface IThingP2PCallback {
onResult(handle: number): void
}
| 回调方法 | 参数 | 说明 |
|---|---|---|
| onResult | handle: number | 连接结果回调,handle 即 sessionId • handle > 0: 连接成功,值为 sessionId • handle = 0: 初始状态 • handle < 0: 连接失败或断开 |
返回值
| 类型 | 说明 |
|---|---|
| string | 连接请求的追踪 ID(traceId) |
会话句柄(handle)值说明
| 值 | 说明 |
|---|---|
| > 0 | 连接成功,值为 sessionId(需要设置到文件传输实例) |
| 0 | 初始状态 |
| -1 | 连接失败 |
| -2 | 连接断开 |
| -3 | 连接超时 |
注意事项
initP2P 初始化onResult 回调中的 handle 参数(当 >0 时)就是 sessionId,需要设置到文件传输实例中onResult 会被多次调用,用于通知会话状态变化使用示例
// 定义回调
const callback: IThingP2PCallback = {
onResult: (handle: number) => {
L.i('P2PDemo', `P2P 连接结果: handle=${handle}`)
if (handle > 0) {
// 连接成功,handle 即为 sessionId,需要设置到文件传输实例
p2pFileTransfer.session = handle
L.i('P2PDemo', `连接成功,已设置 sessionId: ${handle}`)
} else if (handle === 0) {
L.i('P2PDemo', '连接初始化中...')
} else {
// handle < 0 表示连接失败或断开
L.e('P2PDemo', `连接失败或断开: ${handle}`)
}
}
}
// 发起连接
ThingIPCSdk.getP2P().connectWithDevId(
'device_abc123', // 设备 ID
0, // 互联网模式
15000, // 15 秒超时
callback // 回调接口
)
完整示例(结合文件传输)
class P2PManager {
private p2pFileTransfer: ThingP2pFileTransInterface | null = null
private sessionId: number = -1
async connectDevice(deviceId: string) {
// 1. 创建文件传输监听器
const listener: ThingP2pFileTransListener = {
onSessionStatusChanged: (sessionId, sessionStatus) => {
L.i('P2PDemo', `会话状态: ${sessionStatus}`)
return 0
},
// ... 其他回调
}
// 2. 创建文件传输实例
this.p2pFileTransfer = ThingP2pFileTransManager.createP2pFileTransfer(
deviceId,
listener
)
// 3. 定义连接回调
const callback: IThingP2PCallback = {
onResult: (handle: number) => {
if (handle > 0) {
// 🔥 保存 sessionId 并设置到文件传输实例
this.sessionId = handle
if (this.p2pFileTransfer) {
this.p2pFileTransfer.session = handle
L.i('P2PDemo', `✅ 已设置 sessionId: ${handle}`)
}
} else if (handle < 0) {
L.e('P2PDemo', `连接失败: ${handle}`)
this.sessionId = -1
}
}
}
// 4. 发起连接
ThingIPCSdk.getP2P().connectWithDevId(
deviceId,
0, // 互联网模式
15000, // 超时时间
callback
)
}
}
功能描述
断开指定设备的 P2P 连接,释放相关资源。
函数签名
disConnect(handle: number, reason: number, forced: boolean): number
参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| handle | number | 是 | 会话句柄(sessionId),从 connectWithDevId 的回调中获取 |
| reason | number | 是 | 断开原因码:0=正常断开,其他值表示异常断开 |
| forced | boolean | 是 | 是否强制断开:true=立即断开,false=优雅断开 |
返回值
| 类型 | 说明 |
|---|---|
| number | 调用结果:0=成功,其他值=失败 |
注意事项
使用示例
// 假设从连接回调中获取到的 sessionId
const sessionId = 12345
// 方式1:正常断开(优雅关闭)
const result = ThingIPCSdk.getP2P().disConnect(
sessionId, // 会话句柄
0, // 正常断开
false // 优雅断开
)
if (result === 0) {
L.i('P2PDemo', '设备断开成功')
} else {
L.e('P2PDemo', `设备断开失败: ${result}`)
}
// 方式2:强制断开
const forceResult = ThingIPCSdk.getP2P().disConnect(
sessionId, // 会话句柄
1, // 异常断开
true // 强制断开
)
功能描述
反初始化 P2P SDK,释放所有资源。通常在应用退出时调用。
函数签名
deInitP2P(): number
参数说明
无
返回值
| 类型 | 说明 |
|---|---|
| number | 调用结果:0=成功,其他值=失败 |
注意事项
initP2P 才能使用使用示例
// 先断开所有连接
const disconnectResult = ThingIPCSdk.getP2P().disConnect(sessionId, 0, false)
if (disconnectResult !== 0) {
L.e('P2PDemo', `断开连接失败: ${disconnectResult}`)
}
// 反初始化 SDK
const result = ThingIPCSdk.getP2P().deInitP2P()
if (result === 0) {
L.i('P2PDemo', 'SDK 反初始化成功')
} else {
L.e('P2PDemo', `SDK 反初始化失败: ${result}`)
}
功能描述
创建 P2P 文件传输实例。每个设备需要创建独立的文件传输实例,用于查询文件索引、上传下载文件等操作。
函数签名
static createP2pFileTransfer(
deviceId: string,
listener: ThingP2pFileTransListener
): ThingP2pFileTransInterface
参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| deviceId | string | 是 | 设备 ID,必须与连接时使用的设备 ID 一致 |
| listener | ThingP2pFileTransListener | 是 | 文件传输监听器,用于接收各种回调事件 |
返回值
| 类型 | 说明 |
|---|---|
| ThingP2pFileTransInterface | 文件传输实例,提供查询、上传、下载等方法 |
注意事项
session 属性destroyP2pFileTransfer() 方法使用示例
// 1. 创建监听器
const listener: ThingP2pFileTransListener = {
onSessionStatusChanged: (sessionId, status) => {
L.i('P2PDemo', `会话状态: ${status}`)
return 0
},
onFileFinished: (event, filename, index, errCode) => {
L.i('P2PDemo', `文件完成: ${filename}`)
return 0
},
// ... 其他回调
}
// 2. 创建文件传输实例
const p2pFileTransfer = ThingP2pFileTransManager.createP2pFileTransfer(
'device_abc123',
listener
)
// 3. 连接设备后设置 sessionId(重要!)
ThingIPCSdk.getP2P().connectWithDevId(
{ deviceId: 'device_abc123' },
(event) => {
if (event.status > 0) {
// 关键步骤:设置 sessionId
p2pFileTransfer.session = event.status
L.i('P2PDemo', `已设置 sessionId: ${event.status}`)
}
},
() => L.i('P2PDemo', '连接成功'),
(code, msg) => L.e('P2PDemo', `连接失败: ${msg}`)
)
功能描述
获取 P2P 文件传输 SDK 的版本号。
函数签名
static getSDKVersion(): string
参数说明
无
返回值
| 类型 | 说明 |
|---|---|
| string | SDK 版本号,格式如 “1.0.0” |
注意事项
使用示例
const version = ThingP2pFileTransManager.getSDKVersion()
L.i('P2PDemo', `SDK 版本: ${version}`)
功能描述
会话 ID 属性,必须在连接成功后设置。这是 P2P 文件传输的核心标识。
属性类型
session: number
说明
| 属性 | 类型 | 说明 |
|---|---|---|
| session | number | 会话 ID,从 connectWithDevId 的状态回调中获取 |
注意事项
connectWithDevId 的 onStatusChange 回调中的 event.status(当 status > 0 时)使用示例
// 在连接状态回调中设置
ThingIPCSdk.getP2P().connectWithDevId(
{ deviceId: 'device_abc123' },
(event) => {
if (event.status > 0) {
// 设置 sessionId 到文件传输实例
p2pFileTransfer.session = event.status
L.i('P2PDemo', `已设置 session: ${event.status}`)
}
},
() => {},
(code, msg) => {}
)
功能描述
查询指定相册的文件索引列表。返回的文件索引包含文件名、类型、时间等信息,可用于后续的下载操作。
函数签名
queryAlbumFile(
albumName: string,
): number
参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| albumName | string | 是 | 相册名称,如 “Camera”、“Maps” 等 |
返回值
| 类型 | 说明 |
|---|---|
| number | 调用结果:0=成功,其他值=失败 |
注意事项
onP2pResponse 回调中返回(event=12)P2PAlbumFileIndexs,包含 count 和 items 字段使用示例
// 方式一:使用监听器接收数据(推荐)
const listener: ThingP2pFileTransListener = {
onP2pResponse: (event, errCode, data) => {
if (event === 12) { // 查询文件索引事件
if (errCode === 0 && data) {
const result: P2PAlbumFileIndexs = JSON.parse(data)
L.i('P2PDemo', `查询成功: count=${result.count}, items=${result.items.length}`)
// 处理文件列表
result.items.forEach(file => {
L.i('P2PDemo', `文件: ${file.filename}, 类型: ${file.type}`)
})
}
}
return 0
},
// ... 其他回调
}
// 调用查询方法
const result = p2pFileTransfer.queryFileIndexs('Camera', (indexes) => {
// 注意:这个回调可能不会被调用
L.i('P2PDemo', `查询回调: ${indexes.length}`)
})
if (result !== 0) {
L.e('P2PDemo', `查询调用失败: ${result}`)
}
功能描述
开始下载指定的文件列表到本地目录。支持批量下载,下载进度通过监听器回调通知。
函数签名
startDownloadFiles(
albumName: string,
savePath: string,
fileIndexes: string
): number
参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| albumName | string | 是 | 相册名称,必须与查询时使用的相册名一致 |
| savePath | string | 是 | 保存路径,必须是绝对路径且目录必须存在 |
| fileIndexes | string | 是 | 文件索引数组的 JSON 字符串,通过 JSON.stringify(FileIndex[]) 生成 |
返回值
| 类型 | 说明 |
|---|---|
| number | 调用结果:0=成功启动,其他值=失败 |
注意事项
fs.mkdirSync() 确保目录存在onP2pResponse 回调中(查询成功后)调用此方法onFileProgress 回调通知onFileFinished 回调通知使用示例
// 在 onP2pResponse 中接收查询结果并自动下载
onP2pResponse: (event, errCode, data) => {
if (event === 12 && errCode === 0 && data) {
const result: P2PAlbumFileIndexs = JSON.parse(data)
// 准备保存路径
const savePath = '/data/storage/el2/base/haps/entry/files/downloads'
if (!fs.accessSync(savePath)) {
fs.mkdirSync(savePath, true)
}
// 在查询成功回调中调用下载
const fileIndexesJson = JSON.stringify(result.items)
const downloadResult = p2pFileTransfer.startDownloadFiles(
'ipc_sweeper_robot',
savePath,
fileIndexesJson
)
if (downloadResult === 0) {
L.i('P2PDemo', `开始下载 ${result.items.length} 个文件`)
} else {
L.e('P2PDemo', `下载启动失败: ${downloadResult}`)
}
}
return 0
}
功能描述
以流式方式下载文件,适用于地图等需要实时处理的数据。数据通过监听器的 onStreamRecved 回调逐包返回。
函数签名
startDownloadStream(
albumName: string,
fileIndexes: string
): number
参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| albumName | string | 是 | 相册名称 |
| fileIndexes | string | 是 | 文件索引数组的 JSON 字符串 |
返回值
| 类型 | 说明 |
|---|---|
| number | 调用结果:0=成功启动,其他值=失败 |
注意事项
onStreamRecved 回调中处理使用示例
const fileIndexesJson = JSON.stringify([
{ idx: 0, channel: 0, type: 2, filename: 'map.dat', /* ... */ }
])
const result = p2pFileTransfer.startDownloadStream('Maps', fileIndexesJson)
if (result === 0) {
L.i('P2PDemo', '流式下载已启动')
}
功能描述
销毁文件传输实例,释放相关资源。在断开设备连接前应调用此方法。
函数签名
destroy(): void
参数说明
无
返回值
无
注意事项
使用示例
// 销毁文件传输实例
p2pFileTransfer.destroy()
// 然后断开设备连接
ThingIPCSdk.getP2P().disconnect({ deviceId: 'device_abc123' }, () => {}, () => {})
功能描述
会话状态变化回调。当设备连接状态发生变化时触发,可用于监控连接状态。
函数签名
onSessionStatusChanged(sessionId: number, sessionStatus: number): number
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
| sessionId | number | 会话 ID |
| sessionStatus | number | 会话状态(>0: 连接成功,<0: 断开/失败) |
返回值
| 类型 | 说明 |
|---|---|
| number | 固定返回 0 或 sessionId |
状态值说明
| 状态值 | 说明 |
|---|---|
| > 0 | 连接成功,值为 sessionId |
| 0 | 初始状态 |
| < 0 | 连接断开或失败 |
使用示例
onSessionStatusChanged: (sessionId, sessionStatus) => {
if (sessionStatus > 0) {
L.i('P2PDemo', `连接成功,sessionId: ${sessionStatus}`)
} else if (sessionStatus < 0) {
L.e('P2PDemo', '连接断开')
}
return 0
}
功能描述
文件传输完成回调。当单个文件上传或下载完成时触发。
函数签名
onFileFinished(
event: number,
filename: string,
index: number,
errCode: number
): number
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
| event | number | 事件类型(0: 下载, 2: 上传) |
| filename | string | 文件名 |
| index | number | 文件索引 |
| errCode | number | 错误码(0: 成功,其他值: 失败) |
返回值
| 类型 | 说明 |
|---|---|
| number | 固定返回 0 |
使用示例
onFileFinished: (event, filename, index, errCode) => {
if (event === 0) {
L.i('P2PDemo', `文件下载完成: ${filename}, 结果: ${errCode === 0 ? '成功' : '失败'}`)
} else if (event === 2) {
L.i('P2PDemo', `文件上传完成: ${filename}`)
}
return 0
}
功能描述
总体传输进度回调。用于显示整体传输进度。
函数签名
onProgress(event: number, progress: number): number
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
| event | number | 事件类型(0: 下载, 2: 上传) |
| progress | number | 进度百分比(0-100) |
返回值
| 类型 | 说明 |
|---|---|
| number | 固定返回 0 |
使用示例
onProgress: (event, progress) => {
L.i('P2PDemo', `${event === 0 ? '下载' : '上传'}进度: ${progress}%`)
return 0
}
功能描述
单个文件传输进度回调。提供更细粒度的进度信息。
函数签名
onFileProgress(
event: number,
progress: number,
filename: string
): number
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
| event | number | 事件类型(0: 下载, 2: 上传) |
| progress | number | 进度百分比(0-100) |
| filename | string | 文件名 |
返回值
| 类型 | 说明 |
|---|---|
| number | 固定返回 0 |
使用示例
onFileProgress: (event, progress, filename) => {
L.i('P2PDemo', `${filename} ${event === 0 ? '下载' : '上传'}进度: ${progress}%`)
return 0
}
功能描述
P2P 响应回调。用于接收查询等命令的响应数据,这是接收文件索引查询结果的关键回调。
函数签名
onP2pResponse(event: number, errCode: number, data: string): number
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
| event | number | 事件类型(12: 查询文件索引) |
| errCode | number | 错误码(0: 成功,其他值: 失败) |
| data | string | 响应数据(JSON 字符串) |
返回值
| 类型 | 说明 |
|---|---|
| number | 固定返回 0 |
事件类型说明
| 事件值 | 说明 |
|---|---|
| 12 | 查询文件索引响应 |
响应数据格式(event=12 时)
interface P2PAlbumFileIndexs {
count: number // 文件总数
items: FileIndex[] // 文件索引数组
}
注意事项
JSON.parse() 解析使用示例
onP2pResponse: (event, errCode, data) => {
L.i('P2PDemo', `P2P 响应: event=${event}, errCode=${errCode}`)
// 处理查询文件索引的响应
if (event === 12) {
if (errCode === 0 && data) {
try {
const result: P2PAlbumFileIndexs = JSON.parse(data)
L.i('P2PDemo', `查询成功: count=${result.count}, items=${result.items.length}`)
// 🔥 在此处调用下载方法
const savePath = '/data/storage/el2/base/haps/entry/files'
const fileIndexesJson = JSON.stringify(result.items)
p2pFileTransfer.startDownloadFiles('Camera', savePath, fileIndexesJson)
} catch (err) {
L.e('P2PDemo', `解析失败: ${err}`)
}
} else {
L.e('P2PDemo', `查询失败: ${errCode}`)
}
}
return 0
}
功能描述
流式数据接收回调。用于地图等实时数据传输,数据逐包返回。
函数签名
onStreamRecved(
event: number,
sessionId: number,
totalfiles: number,
fileIndex: number,
fileLength: number,
pack: ArrayBuffer,
packageLength: number,
packageType: number
): number
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
| event | number | 事件类型 |
| sessionId | number | 会话 ID |
| totalfiles | number | 总文件数 |
| fileIndex | number | 当前文件索引 |
| fileLength | number | 文件总长度 |
| pack | ArrayBuffer | 数据包内容 |
| packageLength | number | 数据包长度 |
| packageType | number | 数据包类型(1: 新文件开始) |
返回值
| 类型 | 说明 |
|---|---|
| number | 固定返回 0 |
数据包类型说明
| 类型值 | 说明 |
|---|---|
| 1 | 新文件开始(第一个数据包) |
| 其他 | 后续数据包 |
使用示例
onStreamRecved: (event, sessionId, totalfiles, fileIndex, fileLength, pack, packageLength, packageType) => {
if (packageType === 1) {
L.i('P2PDemo', `开始接收新文件: 文件${fileIndex}/${totalfiles}`)
}
L.d('P2PDemo', `收到数据包: 长度=${packageLength}, 总长度=${fileLength}`)
// 处理数据包...
// 例如:保存到本地、实时渲染等
return 0
}
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈