首页
课程
问答
CTF
社区
招聘
峰会
发现
排行榜
知识库
工具下载
看雪20年
看雪商城
证书查询
登录
注册
首页
社区
课程
招聘
发现
问答
CTF
排行榜
知识库
工具下载
峰会
看雪商城
证书查询
社区
HarmonyOS
发新帖
0
0
[原创]碰一碰,秒更新!游戏近场快传助力多人联机无缝组队
发表于: 2025-10-21 16:09
2220
[原创]碰一碰,秒更新!游戏近场快传助力多人联机无缝组队
HarmonyOS SDK
2025-10-21 16:09
2220
在多人联机游戏场景中,玩家组队对战时因游戏版本不一致导致的体验中断问题长期存在。当游戏更新资源包体积庞大时,未及时更新的玩家需依赖网络下载,不仅消耗流量,还因等待时间过长引发用户流失。 HarmonyOS SDK [游戏服务](<mark class="encrypted">349K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1k6i4k6W2L8r3!0H3k6i4u0Q4x3X3g2Z5N6h3q4%4k6h3W2Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3&6K6N6h3#2W2M7W2)9J5c8X3y4F1i4K6u0r3M7$3c8C8i4K6u0r3k6$3q4E0k6g2)9J5k6s2y4W2M7Y4k6A6j5$3g2Q4x3X3c8C8K9i4c8Q4x3V1k6Q4x3@1k6Z5j5g2)9#2k6Y4y4G2N6i4u0U0k6g2)9K6c8r3S2E0M7K6p5`.</mark> "游戏服务")(Game Service Kit)推出的[游戏近场快传服务](<mark class="encrypted">9ceK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1k6i4k6W2L8r3!0H3k6i4u0Q4x3X3g2Z5N6h3q4%4k6h3W2Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3&6K6N6h3#2W2M7W2)9J5c8X3y4F1i4K6u0r3k6r3!0U0i4K6u0r3K9r3q4J5L8h3!0F1P5h3!0K6i4K6u0V1k6%4g2A6k6r3g2K6i4K6u0r3k6$3q4E0k6i4y4W2M7Y4k6A6j5$3g2Q4x3X3c8F1k6h3q4J5j5Y4W2@1M7X3q4F1M7$3k6W2M7W2)9J5k6r3W2F1N6s2u0G2k6s2g2U0N6r3W2G2L8W2)9K6c8X3S2S2i4K6g2X3M7$3!0#2M7X3y4W2i4K6y4p5K9r3#2K6x3b7`.`.</mark> "游戏近场快传服务")支持设备在彼此靠近的情况下进行游戏数据交换,已更新版本的玩家可发送自身资源包给未更新队友,助其迅速完成游戏更新,提升玩家体验。 ### 功能优势 * 无需网络:近场快传技术无需依赖网络,在无网络或网络不稳定的环境下,玩家也能轻松分享游戏资源或组队。玩家只需将两台支持近场快传的设备靠近,即可自动建立连接并开始传输,操作简单快捷。 * 高速传输:游戏近场快传技术传输速度最高可达100MB/S,能够显著提升游戏资源的传输效率。 * 跨设备兼容:游戏近场快传支持多种设备平台,如Phone、PC/2in1、Tablet,实现无缝传输。 ### 使用步骤 1. 设备靠近:玩家需要将支持游戏近场快传的设备靠近,以确保能够建立稳定的通信链路。 2. 选择传输内容:在游戏内或专门的传输应用中,玩家需要选择要传输的游戏资源或数据。 3. 开始传输:一旦设备间建立连接,玩家即可启动传输过程,等待资源传输完成。 ### 接入步骤 以下示例中使用的API说明详见[接口文档](<mark class="encrypted">90cK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1k6i4k6W2L8r3!0H3k6i4u0Q4x3X3g2Z5N6h3q4%4k6h3W2Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3&6K6N6h3#2W2M7W2)9J5c8X3y4F1i4K6u0r3k6r3!0U0i4K6u0r3K9r3q4J5L8h3!0F1P5h3!0K6i4K6u0V1M7X3g2X3k6i4u0W2L8X3y4W2M7#2)9J5c8X3N6S2L8h3g2K6k6i4u0$3K9h3y4W2i4K6u0V1L8X3g2S2M7X3u0&6N6s2u0S2L8Y4y4X3k6i4u0Q4x3@1k6Z5j5g2)9#2k6Y4y4G2N6i4u0U0k6g2)9K6c8r3S2E0M7K6p5`.</mark> "接口文档")。 #### 开发流程  #### 导入模块 导入Game Service Kit及公共模块。 import { abilityAccessCtrl, AbilityConstant, UIAbility, common } from "@kit.AbilityKit"; import { hilog } from '@kit.PerformanceAnalysisKit'; import { gameNearbyTransfer } from '@kit.GameServiceKit'; import { BusinessError } from '@kit.BasicServicesKit'; #### 申请权限 申请ohos.permission.DISTRIBUTED_DATASYNC权限用于设备发现。 let atManager = abilityAccessCtrl.createAtManager(); let uiAbilityContext = this.getUIContext()?.getHostContext() as common.UIAbilityContext; try { atManager.requestPermissionsFromUser(uiAbilityContext, ['ohos.permission.DISTRIBUTED_DATASYNC']).then((data) => { hilog.info(0x0000, 'nearby', '%{public}s', 'data: ' + JSON.stringify(data)); }).catch((err: object) => { hilog.error(0x0000, 'nearby', '%{public}s', 'err: ' + JSON.stringify(err)); }) } catch (err) { hilog.error(0x0000, '[nearby]', '%{public}s', 'error' + (err as Error).message); } #### 创建游戏近场快传服务并注册相关回调 导入相关模块后,需先调用create接口创建游戏近场快传服务,然后注册各回调事件。 public create() { let uiAbilityContext = this.getUIContext()?.getHostContext() as common.UIAbilityContext; let initParam: gameNearbyTransfer.CreateParameters = { abilityName: uiAbilityContext.abilityInfo.name, context: uiAbilityContext, moduleName: uiAbilityContext.abilityInfo.moduleName, needShowSystemUI: false // 是否展示系统UI,true为展示,false为不展示,默认为false }; try { gameNearbyTransfer.create(initParam).then((createResult) => { hilog.info(0x0000, '[nearby]', '%{public}s', 'create success' + createResult.localDeviceName); this.registerCallback(); }).catch((err: BusinessError) => { hilog.error(0x0000, '[nearby]', '%{public}s', 'create error' + (err as Error).message); }) } catch (err) { hilog.error(0x0000, '[nearby]', '%{public}s', 'error' + (err as Error).message); } } // 注册监听 public registerCallback() { try { gameNearbyTransfer.on('connectNotify', connectNotifyCallBack); gameNearbyTransfer.on('receivePackageInfo', receivePackageInfoCallBack); gameNearbyTransfer.on('transferNotify', transferNotifyCallBack); gameNearbyTransfer.on('error', errorCallBack); } catch (err) { hilog.error(0x0000, '[nearby]', '%{public}s', 'error' + (err as Error).message); } } function connectNotifyCallBack(callback: gameNearbyTransfer.ConnectNotification) { } function receivePackageInfoCallBack(callback: gameNearbyTransfer.PackageInfo) { } function transferNotifyCallBack(callback: gameNearbyTransfer.TransferNotification) { } function errorCallBack(callback: gameNearbyTransfer.ReturnResult) { } #### 接收端接受协同 接收端实现onCollaborate回调,回调中调用acceptCollaboration接口接受协同。 export default class EntryAbility extends UIAbility { // 协同回调 onCollaborate(wantParam: Record<string, Object>): AbilityConstant.CollaborateResult { try { gameNearbyTransfer.acceptCollaboration(wantParam); } catch (err) { hilog.error(0x0000, '[nearby]', '%{public}s', 'error' + (err as Error).message); } hilog.info(0x0000, '[nearby]', '%{public}s', 'onCollaborate: accept collaborate'); return AbilityConstant.CollaborateResult.ACCEPT; } } #### 接收端发布自身游戏近场快传服务 接收端调用publishNearbyGame接口发布自身游戏近场快传服务。 try { gameNearbyTransfer.publishNearbyGame().then(() => { hilog.info(0x0000, '[nearby]', '%{public}s', 'publishNearbyGame success'); }).catch((err: BusinessError) => { hilog.error(0x0000, '[nearby]', '%{public}s', 'publishNearbyGame error'); }) } catch (err) { hilog.error(0x0000, '[nearby]', '%{public}s', 'error' + (err as Error).message); } #### 发送端绑定接收端游戏近场快传服务 发送端绑定接收端游戏近场快传服务支持如下两种方式:自动绑定和[选择绑定。](<mark class="encrypted">942K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1k6i4k6W2L8r3!0H3k6i4u0Q4x3X3g2Z5N6h3q4%4k6h3W2Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3&6K6N6h3#2W2M7W2)9J5c8X3y4F1i4K6u0r3k6r3!0U0i4K6u0r3K9r3q4J5L8h3!0F1P5h3!0K6i4K6u0V1k6%4g2A6k6r3g2K6i4K6u0r3k6$3q4E0k6i4y4W2M7Y4k6A6j5$3g2Q4x3X3c8F1k6h3q4J5j5Y4W2@1M7X3q4F1M7$3k6W2M7W2)9J5k6r3q4U0j5$3g2K6M7#2)9J5k6s2m8J5L8$3y4W2k6s2g2J5k6g2)9K6c8X3S2S2i4K6g2X3M7$3!0#2M7X3y4W2i4K6y4p5K9r3#2K6x3g2)9J5x3%4y4W2j5%4c8A6L8$3^5^5y4K6b7@1x3e0l9K6z5e0p5J5y4K6V1`.</mark> "选择绑定。") 这里以自动绑定为例,发送端调用autoBindNearbyGame接口自动绑定接收端近场快传服务。 try { gameNearbyTransfer.autoBindNearbyGame().then(() => { hilog.info(0x0000, '[nearby]', '%{public}s', 'autoBindNearbyGame success'); }).catch((err: BusinessError) => { hilog.error(0x0000, '[nearby]', '%{public}s', 'autoBindNearbyGame error'); }) } catch (err) { hilog.error(0x0000, '[nearby]', '%{public}s', 'error' + (err as Error).message); } #### 接收端发送自身文件信息 收到建链成功回调后,接收端调用sendPackageInfo接口发送自身文件,如版本信息、包信息(包名和扩展数据的字符长度范围:\[0, 2048\]、版本号字符长度范围:\[0, 256\]、文件列表最多10000条)。 function connectNotifyCallBack(callback: gameNearbyTransfer.ConnectNotification) { if (callback.connectState == gameNearbyTransfer.ConnectState.CONNECTED) { // 连接成功回调,判断当前是否为接收端。若当前设备为接收端,请设置为true,否则请设置为false。 let isReceive = true; if (!isReceive) { return; } // 接收端收到连接回调后需要处理,发送资源包信息给发送端 let packageInfo: gameNearbyTransfer.PackageInfo = { name: 'com.huawei.xxxx', files: [], version: '1.1.0', extraData: 'extraData' }; let fileInfo: gameNearbyTransfer.FileInfo = { path: "/xxx/xxxx/files/data.zip", // 使用沙箱路径 hash: 'fileHash' // 可选 }; packageInfo.files?.push(fileInfo); try { gameNearbyTransfer.sendPackageInfo(packageInfo).then(() => { hilog.info(0x0000, '[nearby]', '%{public}s', 'sendPackageInfo success'); }).catch((err: BusinessError) => { hilog.error(0x0000, '[nearby]', '%{public}s', 'sendPackageInfo error'); }); } catch (err) { hilog.error(0x0000, '[nearby]', '%{public}s', 'error' + (err as Error).message); } } } #### 发送端对比后传输资源包 发送端收到接收端发送的版本信息后进行对比,调用replyPackageInfoResult上报对比结果,根据对比结果决定是否需要调用transferPackageData接口发送资源包数据。 function receivePackageInfoCallBack(callback: gameNearbyTransfer.PackageInfo) { // 比较版本,决定是否需要发送资源包,也可以比较文件hash let packageInfoResult: gameNearbyTransfer.PackageInfoResult = { packageInfoResultCode: gameNearbyTransfer.PackageInfoResultCode.PACKAGE_AVAILABLE_COMPARED }; try { // 上报对比结果 gameNearbyTransfer.replyPackageInfoResult(packageInfoResult).then(() => { let packageData: gameNearbyTransfer.PackageData = { name: 'com.huawei.gamenearbydemo', version: '1.0.0', files: [{ srcPath: '/data/xxxx/a.zip', // srcPath是需要发送文件的沙箱路径,详情请参见应用沙箱目录。 destPath: 'xxxx/a.zip' // destPath是接收文件的自定义路径,完整的沙箱路径是fileStoragePath+destPath,详情请参见应用沙箱目录。 }] } try { // 发送资源包 gameNearbyTransfer.transferPackageData(packageData).then(() => { // 发送成功 }).catch((err: BusinessError) => { // 发送异常 hilog.error(0x0000, '[nearby]', '%{public}s', 'error' + (err as Error).message); }); } catch (err) { hilog.error(0x0000, '[nearby]', '%{public}s', 'error' + (err as Error).message); } }).catch((err: BusinessError) => { // 上报异常 hilog.error(0x0000, '[nearby]', '%{public}s', 'error' + (err as Error).message); }); } catch (err) { hilog.error(0x0000, '[nearby]', '%{public}s', 'error' + (err as Error).message); } } #### 处理资源包传输进度信息 发送端和接收端在传输回调中处理传输进度信息。 function transferNotifyCallBack(callback: gameNearbyTransfer.TransferNotification) { if (callback.transferState == gameNearbyTransfer.TransferState.SEND_PROCESS) { // 处理发送进度,如显示进度条和速率 } if (callback.transferState == gameNearbyTransfer.TransferState.SEND_FINISH) { // 发送完成 } if (callback.transferState == gameNearbyTransfer.TransferState.RECEIVE_PROCESS) { // 处理接收进度,如显示进度条和速率 } if (callback.transferState == gameNearbyTransfer.TransferState.RECEIVE_FINISH) { // 接收完成,获取到资源包存储的沙箱路径 let fileStoragePath = callback.fileStoragePath; // 对fileStoragePath下的文件做处理 } } #### 处理已接收资源包后销毁服务 对已接收数据做好处理或转移后,调用destroy接口销毁服务。若服务销毁后再次使用近场快传服务,需重新创建游戏近场快传服务并注册相关回调。 public destroy() { // 取消回调注册 this.unregisterCallback(); // 销毁服务 try { gameNearbyTransfer.destroy().then(() => { hilog.info(0x0000, '[nearby]', '%{public}s', 'destroy success'); }).catch((err: Error) => { hilog.error(0x0000, '[nearby]', '%{public}s', 'destroy error' + (err as Error).message); }); } catch (err) { hilog.error(0x0000, '[nearby]', '%{public}s', 'error' + (err as Error).message); } } public unregisterCallback() { try { gameNearbyTransfer.off('connectNotify', connectNotifyCallBack); gameNearbyTransfer.off('receivePackageInfo', receivePackageInfoCallBack); gameNearbyTransfer.off('transferNotify', transferNotifyCallBack); gameNearbyTransfer.off('error', errorCallBack); // 发送端选择手动绑定接收端且已订阅discovery事件 gameNearbyTransfer.off('discovery', discoveryCallBack); } catch (err) { hilog.error(0x0000, '[nearby]', '%{public}s', 'error' + (err as Error).message); } } function connectNotifyCallBack(callback: gameNearbyTransfer.ConnectNotification) { } function receivePackageInfoCallBack(callback: gameNearbyTransfer.PackageInfo) { } function transferNotifyCallBack(callback: gameNearbyTransfer.TransferNotification) { } function errorCallBack(callback: gameNearbyTransfer.ReturnResult) { } function discoveryCallBack(callback: gameNearbyTransfer.DiscoveryResult) { } **了解更多详情\>\>** 访问[游戏服务联盟官网](<mark class="encrypted">303K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1k6i4k6W2L8r3!0H3k6i4u0Q4x3X3g2Z5N6h3q4%4k6h3W2Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3&6K6N6h3#2W2M7W2)9J5c8X3y4F1i4K6u0r3M7$3c8C8i4K6u0r3k6$3q4E0k6g2)9J5k6s2y4W2M7Y4k6A6j5$3g2Q4x3X3c8C8K9i4c8Q4x3V1k6Q4x3@1k6Z5j5g2)9#2k6Y4y4G2N6i4u0U0k6g2)9K6c8r3S2E0M7K6p5`.</mark> "游戏服务联盟官网") 获取[游戏近场快传开发指导文档](<mark class="encrypted">5dcK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1k6i4k6W2L8r3!0H3k6i4u0Q4x3X3g2Z5N6h3q4%4k6h3W2Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3&6K6N6h3#2W2M7W2)9J5c8X3y4F1i4K6u0r3k6r3!0U0i4K6u0r3K9r3q4J5L8h3!0F1P5h3!0K6i4K6u0V1k6%4g2A6k6r3g2K6i4K6u0r3k6$3q4E0k6i4y4W2M7Y4k6A6j5$3g2Q4x3X3c8F1k6h3q4J5j5Y4W2@1M7X3q4F1M7$3k6W2M7W2)9J5k6r3W2F1N6s2u0G2k6s2g2U0N6r3W2G2L8W2)9K6c8X3S2S2i4K6g2X3M7$3!0#2M7X3y4W2i4K6y4p5K9r3#2K6x3b7`.`.</mark> "游戏近场快传开发指导文档")
传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!!
收藏
・
0
点赞
・
0
打赏
分享
分享到微信
分享到QQ
分享到微博
赞赏记录
参与人
雪币
留言
时间
查看更多
赞赏
×
1 雪花
5 雪花
10 雪花
20 雪花
50 雪花
80 雪花
100 雪花
150 雪花
200 雪花
支付方式:
微信支付
赞赏留言:
快捷留言
感谢分享~
精品文章~
原创内容~
精彩转帖~
助人为乐~
感谢分享~
最新回复
(
0
)
游客
登录
|
注册
方可回帖
回帖
表情
雪币赚取及消费
高级回复
返回
HarmonyOS SDK
258
发帖
190
回帖
0
RANK
关注
私信
他的文章
[原创]HarmonyOS智慧多窗,让应用在任意窗口都“恰到好处”
271
[原创]AI 赋能 Push Kit 场景化消息开发,高效完成鸿蒙应用推送能力接入
472
[原创]HarmonyOS Push Kit 自分类权益 Skill,助力提升权益申请通过率
521
[原创]基于增强QUIC协议优化弱网下的直播观看体验
697
[原创]焕新鸿蒙应用权限管理方案,应用授权体验再升级
609
关于我们
联系我们
企业服务
看雪公众号
专注于PC、移动、智能设备安全研究及逆向工程的开发者社区
看原图
赞赏
×
雪币:
+
留言:
快捷留言
为你点赞!
返回
顶部