如果你也对鸿蒙开发感兴趣,加入“Harmony自习室”吧!扫描下方名片,关注公众号,公众号更新更快,同时也有更多学习资料和技术讨论群。
1、概述
HarmonyOS提供了一套网络网络质量管理的套件(Network Boost Kit),它可以实现网络加速、网络感知、网络质量预测等能力,通过软、硬、芯、端、管、云等全方位的协同解决方案实现网络资源的调优和加速,构筑更可靠、更流畅、更高速的上网体验。
在使用相关API时,需要申请设备网络信息权限:ohos.permission.GET_NETWORK_INFO。需要在entry/src/main路径下的module.json5中配置所需申请的权限。示例代码如下所示:
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.GET_NETWORK_INFO"
}
]
}
}
2、网络质量状况评估
我们可以通过订阅网络质量Qos评估来实现监听网络质量问题,系统按照一定的周期或Qos变化后回调给应用。回调的Qos信息包括数据传输的链路类型、上下行空口实时带宽、上下行空口实时速率、RTT时延等。接口定义如下:
// 订阅Qos信息状态变化
on(type: 'netQosChange', callback: Callback<Array<NetworkQos>>): void
// 取消订阅Qos信息状态变化
off(type: 'netQosChange', callback?: Callback<Array<NetworkQos>>): void
其中NetWorkQos对象是系统返回的网络质量信息。相关结构定义如下:
class NetworkQos {
pathType: PathType // 相应的数据路径上的网络质量信息。
linkUpBandwidth: RateBps // 上行带宽信息。
linkDownBandwidth: RateBps // 下行带宽信息。
linkUpRate: RateBps // 上行速率。
linkDownRate: RateBps // 下行速率。
rttMs: number // RTT时延,取值范围是任意正数。
linkUpBufferDelayMs: number //上行发送空口缓冲时延,取值范围是任意正数。
linkUpBufferCongestionPercent: number // 上行发送空口缓冲时延占总缓冲时间的比例,取值范围[0, 100]。
}
enum PathType {
CELLULAR_PRIMARY = 0 // 蜂窝主卡。
CELLULAR_SECONDARY = 1 // 蜂窝副卡。
WIFI_PRIMARY = 2 // 主WiFi。
WIFI_SECONDARY = 3 // 辅WiFi。
}
type RateBps = number // 带宽或速率的抽象表示。
示例代码如下:
// 导入NetWork Boost Kit模块
import { netQuality } from '@kit.NetworkBoostKit';
import { BusinessError } from '@kit.BasicServicesKit';
// 订阅获取系统Qos信息
// .....
try {
netQuality.on('netQosChange', (list: Array<netQuality.NetworkQos>) => {
if (list.length > 0) {
list.forEach((qos) => {
// 回调信息处理
});
}
});
} catch (err) {
console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
// ...
// 取消订阅Qos信息
// ...
try {
netQuality.off('netQosChange');
} catch (err) {
console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
// ...
3、网络场景识别
应用在订阅网络场景识别后,系统在网络场景实时信息或预测信息发生变化后回调给应用,回调的网络场景信息包括数据传输的链路类型、网络场景类型、数传策略建议、弱信号信息等。接口定义如下:
// 订阅网络场景信息状态变化。
on(type: 'netSceneChange', callback: Callback<Array<NetworkScene>>): void
// 取消订阅网络场景信息状态变化。
off(type: 'netSceneChange', callback?: Callback<Array<NetworkScene>>): void
其中,NetworkScene相关结构如下:
class NetworkScene {
pathType: PathType // 表明相应的数据路径上的网络场景信息。
scene: Scene // 场景状态。
recommendedAction: RecommendedAction // 建议的数传策略。
weakSignalPrediction: WeakSignalPrediction // 弱信号预测相关信息。
}
enum PathType {
CELLULAR_PRIMARY = 0 // 蜂窝主卡。
CELLULAR_SECONDARY = 1 // 蜂窝副卡。
WIFI_PRIMARY = 2 // 主WiFi。
WIFI_SECONDARY = 3 // 辅WiFi。
}
/* 场景类型
'normal':表示正常场景。
'congestion':表示拥塞场景。
'frequentHandover':表示小区切换频繁场景。
'weakSignal':表示弱信号场景。
*/
type Scene = 'normal' | 'congestion' | 'frequentHandover' | 'weakSignal'
/* 应用数传策略建议。
'doCaching':表示做缓存动作。
'suspendData':表示停止发包。
'decreaseData':表示降低发包速率。
'increaseData':表示增加发包速率。
'keepData':表示保持当前发包速率。
*/
type RecommendedAction = 'doCaching' | 'suspendData' | 'decreaseData' | 'increaseData' | 'keepData';
class WeakSignalPrediction { // 弱信号预测相关信息。
isLastPredictionValid: boolean // 最近一次的弱信号预测是否有效,true表示最近一次的弱信号预测依旧有效,false表示最近一次的弱信号预测失效,此时startTime和duration参数忽略。
startTime: number // 预计多长时间进入弱信号(单位:秒),取值范围为0和任意正数。
duration: number //预计在弱信号区域停留时长(单位:秒),取任意正数。取值0,此次预测结果无效。
}
示例代码如下:
// 导入相关模块
import { netQuality } from '@kit.NetworkBoostKit';
import { BusinessError } from '@kit.BasicServicesKit';
// 订阅网络场景识别信息
// ...
try {
netQuality.on('netSceneChange', (list: Array<netQuality.NetworkScene>) => {
if (list.length > 0) {
list.forEach((sceneInfo) => {
// 网络场景识别回调信息处理
if (sceneInfo.scene == 'congestion') {
// 网络拥塞分支处理
}
if (sceneInfo.weakSignalPrediction) {
// 存在弱信号预测信息,对弱信号预测信息进行处理
}
});
}
});
} catch (err) {
console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
// ...
// 取消订阅网络识别信息
// ...
try {
netQuality.off('netSceneChange');
} catch (err) {
console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
// ...
4、应用传输体验反馈
当应用传输体验发生变化时,应用将传输体验和传输的业务类型信息通过实时反馈接口传输给系统网络业务模块,系统网络业务模块进行精细化调度,实现网络加速。
例如:视频类App播放过程中卡顿,将卡顿信息上报后,Network Boost Kit将信息反馈给系统网络加速模块,该模块会记录播放卡顿信息,并根据当前网络情况,启用网络加速能力。
接口定义如下:
// 应用反馈传输体验信息
reportQoe(appQoe: AppQoe): void
其中AppQoe对象定义如下:
class AppQoe {
serviceType: ServiceType // 应用的业务类型。
qoeType: QoeType // 应用体验类型。
}
/*应用业务类型。
'default':表示默认服务类型。
'background':表示后台类型。
'realtimeVoice':表示实时语音类型。
'realtimeVideo':表示实时视频类型。
'callSignaling':表示语音信令类型。
'realtimeGame':表示实时游戏类型。
'normalGame':表示普通游戏类型。
'shortVideo':表示短视频类型。
'longVideo':表示长视频类型。
'livestreamingAnchor':表示直播主播类型。
'livestreamingWatcher':表示直播观看类型。
'download':表示下载类型
'upload':表示上传类型。
'browser':表示浏览页面类型。
*/
type ServiceType = 'default' | 'background' | 'realtimeVoice' | 'realtimeVideo' | 'callSignaling' | 'realtimeGame' | 'normalGame' | 'shortVideo' | 'longVideo' | 'livestreamingAnchor' | 'livestreamingWatcher' | 'download' | 'upload' | 'browser';
/* 应用体验类型
'good' :表示体验良好。
'unknown':表示未知原因。
'serverErr':表示服务器异常。
'noData':表示无数据。
'packetLost':表示丢包。
'packetOutOfOrder':表示乱序。
'highJitter':表示高抖动。
'highLatency':表示高时延。
*/
type QoeType = 'good' | 'unknown' | 'serverErr' | 'noData' | 'packetLost' | 'packetOutOfOrder' | 'highJitter' | 'highLatency';
示例代码如下:
// 导入相关模块
import { netQuality } from '@kit.NetworkBoostKit';
import { BusinessError } from '@kit.BasicServicesKit';
// 调用reportQoe接口将应用传输体验信息通知给系统侧。
// ...
try{
let serviceType: netQuality.ServiceType = 'shortVideo';
let qoeType: netQuality.BadQoeCause = 'serverErr';
let appQoE: netQuality.AppQoe = {
serviceType,
qoeType
};
netQuality.reportQoe(appQoE);
} catch (err) {
console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
// ...
❓ 弱网感知如何判决?
弱网感知判决可归纳为3种方式获取:
👉🏻 方法1(监听系统实时判决):
根据网络场景识别信息,如NetworkScene.scene(weakSignal/congestion)系统直接判决为弱网。
👉🏻 方法2(监听系统预测判决):
根据网络场景识别中的弱信号预测信息,
如NetworkScene.weakSignalPrediction系统预测即将进入弱网区域。
👉🏻 方法3(应用自定义判决):
根据网络质量评估信息,如
NetworkQos(linkUpBandwidth/linkDownBandwidth/rttMs/linkUpBufferDelayMs/linkUpBufferCongestionPercent),应用自定义门限来判决为弱网。
我们可根据自身业务特点,选择其中一种或多种使用。
5、连接迁移
在弱网环境下,系统发起多网迁移(WiFi<->蜂窝,主卡<->副卡等)的过程中,给应用提供连接迁移开始和完成通知,应用根据连接迁移通知的建议进行重建,快速恢复业务,给用户带来平滑、高速、低时延的上网体验。接口定义如下:
// 订阅连接迁移
on(type: 'handoverChange', callback: Callback<HandoverInfo>): void
// 取消订阅连接迁移
off(type: 'handoverChange', callback?: Callback<HandoverInfo>): void
其中HandoverInfo定义如下:
class HandoverInfo {
handoverStart: HandoverStart //表示连接迁移开始信息。
handoverComplete: HandoverComplete // 表示连接迁移完成信息。
}
class HandoverStart {
expires: number // 连接迁移全流程的超时时间,单位为秒,取值为任意正整数或者0。
dataSpeedAction: DataSpeedAction // 老链路的发包建议。
}
class DataSpeedAction {
dataSpeedSimpleAction: DataSpeedSimpleAction // 应用发包策略的简单建议。
linkUpBandwidth: RateBps // 老链路上行带宽。
linkDownBandwidth: RateBps // 老链路下行带宽。
}
type DataSpeedSimpleAction = 'suspendData' | 'decreaseData' | 'increaseData' | 'keepData';
class HandoverComplete {
result: ErrorResult // 连接迁移结果。
/*
true表示还有新链路待激活,系统还会上报HandoverComplete消息,一般发生在连接迁移到多个网络的场景。
false表示当前已经是最后一个HandoverComplete消息,连接迁移流程完成。
*/
handoverContinue: boolean // 是否还有HandoverComplete消息。
oldPathLifeTime: number // 老链路的剩余生存时长,单位为秒,取值为任意正整数或0。
oldDataSpeedAction: DataSpeedAction // 老链路发包建议。
pathTypeChanged: boolean // 新老链路类型是否发生变更。true表示发生变化,如WiFi<->蜂窝。false表示没有发生变化。
newNetHandle: NetHandle // 新链路的NetHandle信息。
reEstAction: ReEstAction // 链路重建类型。
newDataSpeedAction: DataSpeedAction // 新链路发包建议。
}
示例代码如下:
// 导入相关模块
import { netHandover } from '@kit.NetworkBoostKit';
import { BusinessError } from '@kit.BasicServicesKit';
// 订阅迁移信息
// ...
try {
netHandover.on('handoverChange', (info: netHandover.HandoverInfo) => {
if (info.handoverStart) {
// 连接迁移开始回调,应用按照HandoverStart的建议调整数传策略
console.info('handover start');
} else if (info.handoverComplete) {
// 连接迁移完成回调,应用按照HandoverComplete的建议进行调速和重建恢复
console.info('handover complete');
}
});
} catch (err) {
console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
// ...
// 取消订阅连接迁移
// ...
try {
netHandover.off('handoverChange');
} catch (err) {
console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
// ...
6、迁移模式设置
应用可通过该接口变更连接迁移模式,包括委托模式由系统发起连接迁移,和自主模式由应用发起连接迁移。接口定义如下:
// 应用设置迁移模式,默认为委托模式。
setHandoverMode(mode: HandoverMode): void
其中HandoverMode是一个枚举,定义如下:
enum HandoverMode {
DELEGATION = 0 // 委托模式,表示由系统发起连接迁移。应用未调用setHandoverMode接口则默认为该模式。
DISCRETION = 1 // 自主模式,表示由应用发起连接迁移。应用可以通过该接口禁止系统发起连接迁移。在某些场景下,比如该应用切换到后台时,依旧有可能由系统触发切换。
}
示例代码如下:
// 导入相关模块
import { netHandover} from '@kit.NetworkBoostKit';
import { BusinessError } from '@kit.BasicServicesKit';
// 调用setHandoverMode接口,设置为自主模式,禁止系统发起连接迁移
// ...
try{
let mode: netHandover.HandoverMode = netHandover.HandoverMode.DISCRETION;
netHandover.setHandoverMode(mode);
} catch (err) {
console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
// ...