HarmonyOS APP服务发布与发现:SA注册与获取

举报
Jack20 发表于 2026/06/19 19:03:13 2026/06/19
【摘要】 服务发布与发现:SA注册与获取让服务"自动发现",告别硬编码地址 一、背景与动机:为什么需要服务发现? 1.1 传统方式的问题假设你开发了一个支付服务,其他应用需要调用它。传统做法是:// ❌ 硬编码服务地址const paymentService = connectToService('192.168.1.100:8080')// 问题:// 1. 服务地址变化时,所有客户端都要修改//...

服务发布与发现:SA注册与获取

让服务"自动发现",告别硬编码地址

一、背景与动机:为什么需要服务发现?

1.1 传统方式的问题

假设你开发了一个支付服务,其他应用需要调用它。传统做法是:

// ❌ 硬编码服务地址
const paymentService = connectToService('192.168.1.100:8080')

// 问题:
// 1. 服务地址变化时,所有客户端都要修改
// 2. 服务迁移到其他设备,客户端无法知道
// 3. 多实例部署时,无法负载均衡
// 4. 服务不可用时,无法自动切换

**服务发现(Service Discovery)**解决了这些问题:

// ✅ 服务发现
const paymentService = await ServiceManager.getService('com.example.payment')

// 优势:
// 1. 服务地址动态获取
// 2. 自动感知服务状态
// 3. 支持多实例负载均衡
// 4. 服务不可用时自动切换

1.2 鸿蒙的SA机制

鸿蒙使用**SA(System Ability)**机制管理服务:

概念 说明
System Ability 系统能力,即服务
SAMgr 系统能力管理器,负责注册和发现
SA ID 服务的唯一标识
SA Proxy 服务代理,用于跨进程调用

图片.png

1.3 SA vs 传统RPC

对比项 传统RPC 鸿蒙SA
服务地址 硬编码IP:Port 动态发现
服务状态 手动检测 自动感知
负载均衡 客户端实现 系统实现
服务迁移 需要通知 自动适应
权限控制 应用层实现 系统级控制

二、核心原理:SA工作机制

2.1 SA生命周期

sequenceDiagram
    participant SA as System Ability
    participant SAMgr as SAMgr
    participant Client as 客户端
    
    Note over SA: 服务启动
    SA->>SAMgr: 注册(SA ID, IRemoteObject)
    SAMgr->>SAMgr: 保存到注册表
    
    Note over Client: 客户端请求
    Client->>SAMgr: 查询(SA ID)
    SAMgr->>SAMgr: 查找注册表
    SAMgr-->>Client: 返回SA Proxy
    
    Client->>SA: 调用方法(通过Proxy)
    SA-->>Client: 返回结果
    
    Note over SA: 服务停止
    SA->>SAMgr: 注销(SA ID)
    SAMgr->>SAMgr: 从注册表移除
    
    classDef primary fill:#e3f2fd,stroke:#1565c0,stroke-width:2px
    classDef warning fill:#fff3e0,stroke:#e65100,stroke-width:2px
    classDef success fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px
    
    class SA success
    class SAMgr warning
    class Client primary

2.2 SA ID分配

每个SA都有唯一的ID,分为系统SA和应用SA:

// SA ID范围
// 0x00000001 - 0x0000FFFF: 系统SA
// 0x00010000 - 0x0001FFFF: 应用SA

// 系统SA示例
const SAMGR_SA_ID = 0x00000001      // SAMgr自身
const BUNDLE_MGR_SA_ID = 0x00000002 // 包管理服务
const ACCOUNT_MGR_SA_ID = 0x00000003 // 账号管理服务

// 应用SA示例(需要申请)
const MY_PAYMENT_SA_ID = 0x00010001  // 自定义支付服务
const MY_PUSH_SA_ID = 0x00010002     // 自定义推送服务

2.3 SA Proxy获取流程

// SAMgr内部实现(伪代码)
class SAMgr {
    private registry: Map<number, IRemoteObject> = new Map()
    
    // 注册SA
    register(saId: number, remote: IRemoteObject): boolean {
        if (this.registry.has(saId)) {
            // SA已存在,检查是否可覆盖
            return false
        }
        
        this.registry.set(saId, remote)
        return true
    }
    
    // 获取SA
    get(saId: number): IRemoteObject {
        const remote = this.registry.get(saId)
        
        if (!remote) {
            // SA不存在,尝试按需启动
            this.startOnDemand(saId)
            return this.registry.get(saId)
        }
        
        return remote
    }
    
    // 注销SA
    unregister(saId: number): boolean {
        return this.registry.delete(saId)
    }
    
    // 按需启动
    async startOnDemand(saId: number): Promise<void> {
        // 根据SA ID查找对应的进程
        // 启动进程并等待SA注册
    }
}

三、代码实战:实现支付服务SA

3.1 定义SA接口

// IPaymentService.ets
import { IRemoteObject } from '@kit.IPCKit'

/**
 * 支付服务接口
 */
export interface IPaymentService {
    /**
     * 创建支付订单
     * @param order 订单信息
     * @returns 订单ID
     */
    createOrder(order: PaymentOrder): Promise<string>
    
    /**
     * 查询订单状态
     * @param orderId 订单ID
     * @returns 订单状态
     */
    queryOrder(orderId: string): Promise<OrderStatus>
    
    /**
     * 取消订单
     * @param orderId 订单ID
     * @returns 是否成功
     */
    cancelOrder(orderId: string): Promise<boolean>
    
    /**
     * 获取RemoteObject引用
     */
    asObject(): IRemoteObject
}

/**
 * 支付订单
 */
export interface PaymentOrder {
    amount: number          // 金额(分)
    currency: string        // 币种
    subject: string         // 商品名称
    body?: string           // 商品描述
    userId: string          // 用户ID
    notifyUrl?: string      // 回调URL
}

/**
 * 订单状态
 */
export interface OrderStatus {
    orderId: string
    status: 'pending' | 'paid' | 'failed' | 'cancelled'
    amount: number
    paidAt?: number
    transactionId?: string
}

// 请求码定义
export const enum PaymentCode {
    CREATE_ORDER = 1,
    QUERY_ORDER = 2,
    CANCEL_ORDER = 3
}

// SA ID定义
export const PAYMENT_SA_ID = 0x00010001

// 接口描述符
export const PAYMENT_DESCRIPTOR = 'com.example.IPaymentService'

3.2 实现SA服务端

// PaymentService.ets
import { SystemAbility, MessageParcel, IRemoteObject } from '@kit.IPCKit'
import { IPaymentService, PaymentOrder, OrderStatus, PaymentCode, PAYMENT_SA_ID, PAYMENT_DESCRIPTOR } from './IPaymentService'
import hilog from '@ohos.hilog'

const TAG = 'PaymentService'
const DOMAIN = 0xFF00

/**
 * 支付服务SA实现
 */
export default class PaymentService extends SystemAbility implements IPaymentService {
    // 订单存储(实际应使用数据库)
    private orders: Map<string, OrderInfo> = new Map()
    
    /**
     * SA启动时调用
     */
    onStart(): void {
        hilog.info(DOMAIN, TAG, 'PaymentService onStart')
        
        // 注册到SAMgr
        this.registerToSAMgr()
        
        // 初始化资源
        this.initialize()
    }
    
    /**
     * SA停止时调用
     */
    onStop(): void {
        hilog.info(DOMAIN, TAG, 'PaymentService onStop')
        
        // 注销SA
        this.unregisterFromSAMgr()
        
        // 清理资源
        this.cleanup()
    }
    
    /**
     * 注册到SAMgr
     */
    private registerToSAMgr(): void {
        // SystemAbility基类会自动注册
        // 这里可以添加额外的注册逻辑
        hilog.info(DOMAIN, TAG, `Registered with SA ID: ${PAYMENT_SA_ID}`)
    }
    
    /**
     * 注销SA
     */
    private unregisterFromSAMgr(): void {
        hilog.info(DOMAIN, TAG, 'Unregistered from SAMgr')
    }
    
    /**
     * 初始化
     */
    private initialize(): void {
        // 加载订单数据
        // 连接支付渠道
        hilog.info(DOMAIN, TAG, 'PaymentService initialized')
    }
    
    /**
     * 清理资源
     */
    private cleanup(): void {
        this.orders.clear()
        hilog.info(DOMAIN, TAG, 'PaymentService cleaned up')
    }
    
    /**
     * 处理远程请求
     */
    onRemoteRequest(code: number, data: MessageParcel, reply: MessageParcel): boolean {
        hilog.info(DOMAIN, TAG, `onRemoteRequest: code=${code}`)
        
        switch (code) {
            case PaymentCode.CREATE_ORDER:
                return this.handleCreateOrder(data, reply)
                
            case PaymentCode.QUERY_ORDER:
                return this.handleQueryOrder(data, reply)
                
            case PaymentCode.CANCEL_ORDER:
                return this.handleCancelOrder(data, reply)
                
            default:
                hilog.warn(DOMAIN, TAG, `Unknown code: ${code}`)
                return false
        }
    }
    
    /**
     * 处理创建订单请求
     */
    private handleCreateOrder(data: MessageParcel, reply: MessageParcel): boolean {
        try {
            // 读取订单信息
            const orderJson = data.readString()
            const order: PaymentOrder = JSON.parse(orderJson)
            
            // 创建订单
            const orderId = this.createOrderInternal(order)
            
            // 写入响应
            reply.writeString(orderId)
            
            hilog.info(DOMAIN, TAG, `Order created: ${orderId}`)
            return true
        } catch (err) {
            hilog.error(DOMAIN, TAG, `Create order failed: ${err.message}`)
            reply.writeString('')
            return false
        }
    }
    
    /**
     * 处理查询订单请求
     */
    private handleQueryOrder(data: MessageParcel, reply: MessageParcel): boolean {
        try {
            const orderId = data.readString()
            const status = this.queryOrderInternal(orderId)
            
            reply.writeString(JSON.stringify(status))
            return true
        } catch (err) {
            hilog.error(DOMAIN, TAG, `Query order failed: ${err.message}`)
            return false
        }
    }
    
    /**
     * 处理取消订单请求
     */
    private handleCancelOrder(data: MessageParcel, reply: MessageParcel): boolean {
        try {
            const orderId = data.readString()
            const success = this.cancelOrderInternal(orderId)
            
            reply.writeBoolean(success)
            return true
        } catch (err) {
            hilog.error(DOMAIN, TAG, `Cancel order failed: ${err.message}`)
            return false
        }
    }
    
    /**
     * 创建订单(内部实现)
     */
    private createOrderInternal(order: PaymentOrder): string {
        // 生成订单ID
        const orderId = `ORD${Date.now()}${Math.random().toString(36).substr(2, 9)}`
        
        // 保存订单
        const orderInfo: OrderInfo = {
            orderId: orderId,
            order: order,
            status: 'pending',
            createdAt: Date.now()
        }
        
        this.orders.set(orderId, orderInfo)
        
        // 异步处理支付
        this.processPayment(orderId, order)
        
        return orderId
    }
    
    /**
     * 查询订单(内部实现)
     */
    private queryOrderInternal(orderId: string): OrderStatus {
        const info = this.orders.get(orderId)
        
        if (!info) {
            return {
                orderId: orderId,
                status: 'failed',
                amount: 0
            }
        }
        
        return {
            orderId: info.orderId,
            status: info.status,
            amount: info.order.amount,
            paidAt: info.paidAt,
            transactionId: info.transactionId
        }
    }
    
    /**
     * 取消订单(内部实现)
     */
    private cancelOrderInternal(orderId: string): boolean {
        const info = this.orders.get(orderId)
        
        if (!info || info.status !== 'pending') {
            return false
        }
        
        info.status = 'cancelled'
        return true
    }
    
    /**
     * 处理支付(异步)
     */
    private async processPayment(orderId: string, order: PaymentOrder): Promise<void> {
        // 模拟支付处理
        await new Promise(resolve => setTimeout(resolve, 2000))
        
        const info = this.orders.get(orderId)
        if (!info || info.status !== 'pending') {
            return
        }
        
        // 模拟支付成功
        info.status = 'paid'
        info.paidAt = Date.now()
        info.transactionId = `TXN${Date.now()}`
        
        hilog.info(DOMAIN, TAG, `Payment completed: ${orderId}`)
        
        // 通知回调
        if (order.notifyUrl) {
            this.notifyPayment(order.notifyUrl, info)
        }
    }
    
    /**
     * 通知支付结果
     */
    private async notifyPayment(url: string, info: OrderInfo): Promise<void> {
        // 发送HTTP通知
        hilog.info(DOMAIN, TAG, `Notify: ${url}`)
    }
    
    /**
     * 实现IPaymentService接口
     */
    async createOrder(order: PaymentOrder): Promise<string> {
        return this.createOrderInternal(order)
    }
    
    async queryOrder(orderId: string): Promise<OrderStatus> {
        return this.queryOrderInternal(orderId)
    }
    
    async cancelOrder(orderId: string): Promise<boolean> {
        return this.cancelOrderInternal(orderId)
    }
    
    asObject(): IRemoteObject {
        return this
    }
}

/**
 * 订单信息(内部)
 */
interface OrderInfo {
    orderId: string
    order: PaymentOrder
    status: 'pending' | 'paid' | 'failed' | 'cancelled'
    createdAt: number
    paidAt?: number
    transactionId?: string
}

3.3 配置SA

// module.json5
{
    "module": {
        "name": "entry",
        "type": "entry",
        "abilities": [
            {
                "name": "PaymentService",
                "srcEntry": "./ets/PaymentService.ets",
                "type": "service",
                "visible": true,
                "systemAbility": {
                    "saId": 4294967297,  // 0x00010001的十进制
                    "permission": "ohos.permission.PAYMENT_SERVICE",
                    "distributed": true,  // 支持分布式
                    "dumpLevel": 1
                }
            }
        ]
    }
}

3.4 客户端获取SA

// PaymentClient.ets
import { samgr, IRemoteObject } from '@kit.IPCKit'
import { IPaymentService, PaymentOrder, OrderStatus, PAYMENT_SA_ID, PAYMENT_DESCRIPTOR } from './IPaymentService'
import { MessageParcel } from '@kit.IPCKit'
import hilog from '@ohos.hilog'

const TAG = 'PaymentClient'
const DOMAIN = 0xFF00

/**
 * 支付服务代理
 */
export class PaymentProxy implements IPaymentService {
    private remote: IRemoteObject
    
    constructor(remote: IRemoteObject) {
        this.remote = remote
    }
    
    /**
     * 创建订单
     */
    async createOrder(order: PaymentOrder): Promise<string> {
        const data = MessageParcel.create()
        const reply = MessageParcel.create()
        
        try {
            data.writeString(JSON.stringify(order))
            
            const result = this.remote.sendRequest(1, data, reply)
            if (!result) {
                throw new Error('sendRequest failed')
            }
            
            return reply.readString()
        } finally {
            data.reclaim()
            reply.reclaim()
        }
    }
    
    /**
     * 查询订单
     */
    async queryOrder(orderId: string): Promise<OrderStatus> {
        const data = MessageParcel.create()
        const reply = MessageParcel.create()
        
        try {
            data.writeString(orderId)
            
            this.remote.sendRequest(2, data, reply)
            
            const json = reply.readString()
            return JSON.parse(json) as OrderStatus
        } finally {
            data.reclaim()
            reply.reclaim()
        }
    }
    
    /**
     * 取消订单
     */
    async cancelOrder(orderId: string): Promise<boolean> {
        const data = MessageParcel.create()
        const reply = MessageParcel.create()
        
        try {
            data.writeString(orderId)
            
            this.remote.sendRequest(3, data, reply)
            
            return reply.readBoolean()
        } finally {
            data.reclaim()
            reply.reclaim()
        }
    }
    
    asObject(): IRemoteObject {
        return this.remote
    }
}

/**
 * 支付服务客户端
 */
export class PaymentClient {
    private paymentService: IPaymentService = null
    
    /**
     * 连接支付服务
     */
    async connect(): Promise<void> {
        try {
            // 从SAMgr获取SA
            const remote = await samgr.getSystemAbility(PAYMENT_SA_ID)
            
            if (!remote) {
                throw new Error('Payment service not available')
            }
            
            // 创建代理
            this.paymentService = new PaymentProxy(remote)
            
            hilog.info(DOMAIN, TAG, 'Connected to payment service')
        } catch (err) {
            hilog.error(DOMAIN, TAG, `Connect failed: ${err.message}`)
            throw err
        }
    }
    
    /**
     * 创建支付订单
     */
    async createOrder(order: PaymentOrder): Promise<string> {
        if (!this.paymentService) {
            await this.connect()
        }
        
        return this.paymentService.createOrder(order)
    }
    
    /**
     * 查询订单状态
     */
    async queryOrder(orderId: string): Promise<OrderStatus> {
        if (!this.paymentService) {
            await this.connect()
        }
        
        return this.paymentService.queryOrder(orderId)
    }
    
    /**
     * 取消订单
     */
    async cancelOrder(orderId: string): Promise<boolean> {
        if (!this.paymentService) {
            await this.connect()
        }
        
        return this.paymentService.cancelOrder(orderId)
    }
    
    /**
     * 断开连接
     */
    disconnect(): void {
        this.paymentService = null
        hilog.info(DOMAIN, TAG, 'Disconnected from payment service')
    }
}

3.5 使用示例

// PaymentPage.ets
import { PaymentClient, PaymentOrder } from './PaymentClient'
import hilog from '@ohos.hilog'

const TAG = 'PaymentPage'
const DOMAIN = 0xFF00

@Entry
@Component
struct PaymentPage {
    @State orderId: string = ''
    @State orderStatus: string = ''
    @State isLoading: boolean = false
    
    private paymentClient: PaymentClient = new PaymentClient()
    
    async aboutToAppear() {
        try {
            await this.paymentClient.connect()
        } catch (err) {
            hilog.error(DOMAIN, TAG, `Connect failed: ${err.message}`)
        }
    }
    
    aboutToDisappear() {
        this.paymentClient.disconnect()
    }
    
    /**
     * 创建订单
     */
    async createOrder(): Promise<void> {
        this.isLoading = true
        
        try {
            const order: PaymentOrder = {
                amount: 10000,  // 100元
                currency: 'CNY',
                subject: '鸿蒙开发课程',
                body: '从入门到精通',
                userId: 'user001',
                notifyUrl: 'https://example.com/notify'
            }
            
            this.orderId = await this.paymentClient.createOrder(order)
            this.orderStatus = '订单创建成功'
            
            hilog.info(DOMAIN, TAG, `Order created: ${this.orderId}`)
            
            // 轮询订单状态
            this.pollOrderStatus()
        } catch (err) {
            this.orderStatus = `创建失败: ${err.message}`
        } finally {
            this.isLoading = false
        }
    }
    
    /**
     * 轮询订单状态
     */
    private async pollOrderStatus(): Promise<void> {
        for (let i = 0; i < 10; i++) {
            await new Promise(resolve => setTimeout(resolve, 2000))
            
            try {
                const status = await this.paymentClient.queryOrder(this.orderId)
                this.orderStatus = `订单状态: ${status.status}`
                
                if (status.status === 'paid') {
                    // 支付成功
                    this.orderStatus = '支付成功!'
                    break
                } else if (status.status === 'failed') {
                    this.orderStatus = '支付失败'
                    break
                }
            } catch (err) {
                hilog.error(DOMAIN, TAG, `Query failed: ${err.message}`)
            }
        }
    }
    
    /**
     * 取消订单
     */
    async cancelOrder(): Promise<void> {
        if (!this.orderId) {
            return
        }
        
        try {
            const success = await this.paymentClient.cancelOrder(this.orderId)
            
            if (success) {
                this.orderStatus = '订单已取消'
            } else {
                this.orderStatus = '取消失败'
            }
        } catch (err) {
            this.orderStatus = `取消失败: ${err.message}`
        }
    }
    
    build() {
        Column() {
            Text('支付服务示例')
                .fontSize(24)
                .fontWeight(FontWeight.Bold)
                .margin({ bottom: 20 })
            
            if (this.isLoading) {
                LoadingProgress()
                    .width(50)
                    .height(50)
            } else {
                // 订单信息
                if (this.orderId) {
                    Text(`订单ID: ${this.orderId}`)
                        .fontSize(14)
                        .margin({ bottom: 10 })
                }
                
                Text(this.orderStatus)
                    .fontSize(16)
                    .margin({ bottom: 20 })
                
                // 操作按钮
                Row() {
                    Button('创建订单')
                        .onClick(() => this.createOrder())
                        .margin({ right: 10 })
                    
                    Button('取消订单')
                        .onClick(() => this.cancelOrder())
                        .enabled(!!this.orderId)
                }
            }
        }
        .width('100%')
        .height('100%')
        .justifyContent(FlexAlign.Center)
    }
}

四、踩坑与注意事项

4.1 坑一:SA ID冲突

问题:多个应用使用相同的SA ID会导致冲突。

// ❌ 使用系统SA ID范围
const MY_SA_ID = 0x00000010  // 系统SA ID,可能冲突

// ✅ 使用应用SA ID范围
const MY_SA_ID = 0x00010001  // 应用SA ID起始

// ✅ 更好:向系统申请专用SA ID
// 在profile中声明,系统会分配唯一ID

4.2 坑二:SA未启动

问题:SA可能未启动,获取时返回null。

// ❌ 直接使用,不检查
const remote = await samgr.getSystemAbility(SA_ID)
remote.sendRequest(...)  // remote可能是null

// ✅ 检查并处理
async function getSA(saId: number): Promise<IRemoteObject> {
    let remote = await samgr.getSystemAbility(saId)
    
    if (!remote) {
        // SA未启动,尝试启动
        await samgr.startSystemAbility(saId)
        
        // 等待SA启动
        await new Promise(resolve => setTimeout(resolve, 1000))
        
        // 再次获取
        remote = await samgr.getSystemAbility(saId)
    }
    
    if (!remote) {
        throw new Error('SA not available')
    }
    
    return remote
}

4.3 坑三:权限不足

问题:访问系统SA需要相应权限。

// ❌ 无权限访问系统SA
const remote = await samgr.getSystemAbility(ACCOUNT_MGR_SA_ID)
// 可能抛出权限异常

// ✅ 检查权限
async function getAccountSA(): Promise<IRemoteObject | null> {
    try {
        return await samgr.getSystemAbility(ACCOUNT_MGR_SA_ID)
    } catch (err) {
        if (err.code === 201 || err.code === 202) {
            // 权限不足
            hilog.error(DOMAIN, TAG, 'Permission denied')
            return null
        }
        throw err
    }
}

4.4 坑四:SA状态监听

问题:SA可能随时停止,需要监听状态变化。

// ✅ 注册SA状态监听
import { samgr, SystemAbilityStatusChange } from '@kit.IPCKit'

class SAStatusListener {
    // 注册状态变化监听
    registerListener(saId: number): void {
        const listener: SystemAbilityStatusChange = {
            onAddSystemAbility: (saId: number, deviceId: string) => {
                hilog.info(DOMAIN, TAG, `SA ${saId} added on ${deviceId}`)
                // SA可用,可以获取使用
            },
            
            onRemoveSystemAbility: (saId: number, deviceId: string) => {
                hilog.info(DOMAIN, TAG, `SA ${saId} removed on ${deviceId}`)
                // SA不可用,需要处理
            }
        }
        
        samgr.subscribeSystemAbility(saId, listener)
    }
    
    // 注销监听
    unregisterListener(saId: number): void {
        samgr.unsubscribeSystemAbility(saId)
    }
}

五、HarmonyOS 6适配指南

5.1 API变更

变更项 HarmonyOS 5 HarmonyOS 6
导入方式 @ohos.samgr @kit.IPCKit
获取SA getSystemAbility 同上
启动SA startSystemAbility 同上
分布式支持 有限 完整支持

5.2 新增功能

// HarmonyOS 6新增:分布式SA
import { samgr } from '@kit.IPCKit'

// 获取远程设备上的SA
async function getRemoteSA(deviceId: string, saId: number): Promise<IRemoteObject> {
    const remote = await samgr.getSystemAbility(saId, deviceId)
    return remote
}

// HarmonyOS 6新增:SA能力查询
async function querySACapability(saId: number): Promise<SACapability> {
    const capability = await samgr.querySystemAbilityInfo(saId)
    
    return {
        isRunning: capability.isRunning,
        isDistributed: capability.isDistributed,
        permission: capability.permission,
        deviceId: capability.deviceId
    }
}

// HarmonyOS 6新增:批量获取SA
async function batchGetSA(saIds: number[]): Promise<Map<number, IRemoteObject>> {
    const results = new Map()
    
    for (const saId of saIds) {
        const remote = await samgr.getSystemAbility(saId)
        if (remote) {
            results.set(saId, remote)
        }
    }
    
    return results
}

5.3 分布式SA示例

// DistributedPayment.ets
import { samgr, deviceManager } from '@kit.IPCKit'
import hilog from '@ohos.hilog'

const TAG = 'DistributedPayment'
const DOMAIN = 0xFF00

/**
 * 分布式支付服务客户端
 * 可以调用本地或远程设备上的支付服务
 */
export class DistributedPaymentClient {
    /**
     * 获取最佳支付服务
     * 优先本地,其次远程设备
     */
    async getBestPaymentService(): Promise<IPaymentService> {
        // 尝试本地
        let remote = await samgr.getSystemAbility(PAYMENT_SA_ID)
        
        if (remote) {
            hilog.info(DOMAIN, TAG, 'Using local payment service')
            return new PaymentProxy(remote)
        }
        
        // 尝试远程设备
        const devices = await this.getAvailableDevices()
        
        for (const device of devices) {
            remote = await samgr.getSystemAbility(PAYMENT_SA_ID, device.deviceId)
            
            if (remote) {
                hilog.info(DOMAIN, TAG, `Using remote payment service on ${device.deviceName}`)
                return new PaymentProxy(remote)
            }
        }
        
        throw new Error('No payment service available')
    }
    
    /**
     * 获取可用设备列表
     */
    private async getAvailableDevices(): Promise<DeviceInfo[]> {
        // 使用deviceManager获取设备列表
        const dmInstance = deviceManager.createDeviceManager('com.example.app')
        const devices = dmInstance.getTrustedDeviceListSync()
        
        return devices.filter(d => d.deviceState === 'ONLINE')
    }
}

六、总结

6.1 核心要点回顾

图片.png

6.2 最佳实践清单

  • [ ] 使用正确的SA ID范围
  • [ ] 检查SA是否可用
  • [ ] 处理权限不足的情况
  • [ ] 注册SA状态监听
  • [ ] 实现SA Proxy封装调用
  • [ ] 支持分布式场景
  • [ ] 正确配置SA权限

6.3 SA vs 其他方案

场景 推荐方案
系统服务 系统SA
应用服务 应用SA
跨应用通信 SA或DataShare
跨设备通信 分布式SA
简单数据共享 DataShare
复杂业务逻辑 SA

下一篇预告:《跨进程回调:RemoteObject回调机制》——深入跨进程回调的实现原理。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。