网络连接管理提供管理网络一些基础能力,包括WiFi/蜂窝/Ethernet等多网络连接优先级管理、网络质量评估、订阅默认/指定网络连接状态变化、查询网络连接信息、DNS解析等功能。
说明
为了保证应用的运行效率,大部分API调用都是异步的,对于异步调用的API均提供了callback和Promise两种方式,以下示例均采用promise函数,更多方式可以查阅API参考。
网络连接管理的典型场景如下所示。
具体开发方式介绍如下。
完整的JS API说明以及实例代码请参考:网络连接管理。
// 引入包名。
import { connection } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';
let netSpecifier: connection.NetSpecifier = {
netCapabilities: {
// 假设当前默认网络是WiFi,需要创建蜂窝网络连接,可指定网络类型为蜂窝网。
bearerTypes: [connection.NetBearType.BEARER_CELLULAR],
// 指定网络能力为Internet。
networkCap: [connection.NetCap.NET_CAPABILITY_INTERNET]
},
};
// 指定超时时间为10s(默认值为0)。
let timeout = 10 * 1000;
// 创建NetConnection对象。
let conn = connection.createNetConnection(netSpecifier, timeout);
// 订阅指定网络状态变化的通知。
conn.register((err: BusinessError, data: void) => {
console.log(JSON.stringify(err));
});
// 订阅事件,如果当前指定网络可用,通过on_netAvailable通知用户。
conn.on('netAvailable', ((data: connection.NetHandle) => {
console.log("net is available, netId is " + data.netId);
}));
// 订阅事件,如果当前指定网络不可用,通过on_netUnavailable通知用户。
conn.on('netUnavailable', ((data: void) => {
console.log("net is unavailable, data is " + JSON.stringify(data));
}));
// 当不使用该网络时,可以调用该对象的unregister()方法,取消订阅。
conn.unregister((err: BusinessError, data: void) => {
});
根据当前网络状态及网络质量情况,默认网络可能会发生变化,如下所示。
在WiFi弱信号的情况下,默认网络可能会切换到蜂窝网络。
在蜂窝网络状态差的情况下,默认网络可能会切换到WiFi。
关闭WiFi后,默认网络可能会切换到蜂窝网络。
关闭蜂窝网络后,默认网络可能会切换到WiFi。
在WiFi弱信号的情况下,默认网络可能会切换到其他WiFi(存在跨网情况)。
在蜂窝网络状态差的情况下,默认网络可能会切换到其他蜂窝(存在跨网情况)。
应用能够快速迁移到新默认网络上,具体做法如下。
import { connection } from '@kit.NetworkKit';
async function test() {
const netConnection = connection.createNetConnection();
/* 监听默认网络改变。 */
netConnection.on('netAvailable', (data: connection.NetHandle) => {
console.log(JSON.stringify(data));
});
}
原网络连接使用http模块建立网络连接
如果您使用了http模块建立网络连接,由于该模块没有提供Close接口用于关闭Socket,在切换默认网络并建立新的网络连接后原有Socket不会立即关闭。因此请切换使用Remote Communication Kit建立网络连接。
import { rcp } from '@kit.RemoteCommunicationKit';
import { connection } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';
let session = rcp.createSession();
async function useRcp() {
/* 建立rcp请求。 */
try {
const request = await session.get('https://www.example.com');
console.info(request.statusCode.toString());
} catch (e) {
console.error(e.code.toString());
}
}
async function rcpTest() {
const netConnection = connection.createNetConnection();
netConnection.on('netAvailable', async (netHandle: connection.NetHandle) => {
/* 发生默认网络切换,重新建立session。 */
session.close();
session = rcp.createSession();
useRcp();
});
try {
netConnection.register(() => {
});
useRcp();
} catch (e) {
console.error(e.code.toString());
}
}
import { connection, socket } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';
let sock: socket.TCPSocket = socket.constructTCPSocketInstance();
async function useSocket() {
let tcpConnectOptions: socket.TCPConnectOptions = {
address: {
address: '192.168.xx.xxx',
port: 8080
},
timeout: 6000
}
/* 建立socket连接。 */
sock.connect(tcpConnectOptions, (err: BusinessError) => {
if (err) {
console.error('connect fail');
return;
}
console.log('connect success');
/* 通过socket发送数据。 */
let tcpSendOptions: socket.TCPSendOptions = {
data: 'Hello, server!'
}
sock.send(tcpSendOptions).then(() => {
console.log('send success');
}).catch((err: BusinessError) => {
console.error('send fail');
});
})
}
async function socketTest() {
const netConnection = connection.createNetConnection();
netConnection.on('netAvailable', async (netHandle: connection.NetHandle) => {
console.log('default network changed');
await sock.close();
sock = socket.constructTCPSocketInstance();
useSocket();
});
try {
netConnection.register(() => {
});
useSocket();
} catch (e) {
console.error(e.code.toString());
}
}
请在监控到默认网络变化后关闭原有Socket并重新建立Socket连接。
// 引入包名。
import { connection } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';
// 构造单例对象。
export class GlobalContext {
public netList: connection.NetHandle[] = [];
private constructor() {}
private static instance: GlobalContext;
private _objects = new Map<string, Object>();
public static getContext(): GlobalContext {
if (!GlobalContext.instance) {
GlobalContext.instance = new GlobalContext();
}
return GlobalContext.instance;
}
getObject(value: string): Object | undefined {
return this._objects.get(value);
}
setObject(key: string, objectClass: Object): void {
this._objects.set(key, objectClass);
}
}
// 获取所有处于连接状态的网络列表。
connection.getAllNets().then((data: connection.NetHandle[]) => {
console.info("Succeeded to get data: " + JSON.stringify(data));
if (data) {
GlobalContext.getContext().netList = data;
}
});
import { connection } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';
// 构造单例对象。
export class GlobalContext {
public netList: connection.NetHandle[] = [];
public netHandle: connection.NetHandle|null = null;
private constructor() {}
private static instance: GlobalContext;
private _objects = new Map<string, Object>();
public static getContext(): GlobalContext {
if (!GlobalContext.instance) {
GlobalContext.instance = new GlobalContext();
}
return GlobalContext.instance;
}
getObject(value: string): Object | undefined {
return this._objects.get(value);
}
setObject(key: string, objectClass: Object): void {
this._objects.set(key, objectClass);
}
}
// 调用getDefaultNet方法,获取默认的数据网络(NetHandle)。
connection.getDefaultNet().then((data:connection.NetHandle) => {
if (data.netId == 0) {
// 当前无默认网络时,获取的netHandler的netid为0,属于异常情况,需要额外处理。
return;
}
if (data) {
console.info("getDefaultNet get data: " + JSON.stringify(data));
GlobalContext.getContext().netHandle = data;
// 获取netHandle对应网络的能力信息。能力信息包含了网络类型、网络具体能力等网络信息。
connection.getNetCapabilities(GlobalContext.getContext().netHandle).then(
(data: connection.NetCapabilities) => {
console.info("getNetCapabilities get data: " + JSON.stringify(data));
// 获取网络类型(bearerTypes)。
let bearerTypes: Set<number> = new Set(data.bearerTypes);
let bearerTypesNum = Array.from(bearerTypes.values());
for (let item of bearerTypesNum) {
if (item == 0) {
// 蜂窝网络。
console.log(JSON.stringify("BEARER_CELLULAR"));
} else if (item == 1) {
// Wi-Fi网络。
console.log(JSON.stringify("BEARER_WIFI"));
} else if (item == 3) {
// 以太网网络。
console.log(JSON.stringify("BEARER_ETHERNET"));
}
}
// 获取网络具体能力(networkCap)。
let itemNumber : Set<number> = new Set(data.networkCap);
let dataNumber = Array.from(itemNumber.values());
for (let item of dataNumber) {
if (item == 0) {
// 表示网络可以访问运营商的MMSC(Multimedia Message Service,多媒体短信服务)发送和接收彩信。
console.log(JSON.stringify("NET_CAPABILITY_MMS"));
} else if (item == 11) {
// 表示网络流量未被计费。
console.log(JSON.stringify("NET_CAPABILITY_NOT_METERED"));
} else if (item == 12) {
// 表示该网络应具有访问Internet的能力,该能力由网络提供者设置。
console.log(JSON.stringify("NET_CAPABILITY_INTERNET"));
} else if (item == 15) {
// 表示网络不使用VPN(Virtual Private Network,虚拟专用网络)。
console.log(JSON.stringify("NET_CAPABILITY_NOT_VPN"));
} else if (item == 16) {
// 表示该网络访问Internet的能力被网络管理成功验证,该能力由网络管理模块设置。
console.log(JSON.stringify("NET_CAPABILITY_VALIDATED"));
}
}
})
}
});
// 获取netHandle对应网络的连接信息。连接信息包含了链路信息、路由信息等。
connection.getConnectionProperties(GlobalContext.getContext().netHandle).then((data: connection.ConnectionProperties) => {
console.info("getConnectionProperties get data: " + JSON.stringify(data));
})
// 调用getAllNets,获取所有处于连接状态的网络列表(Array)。
connection.getAllNets().then((data: connection.NetHandle[]) => {
console.info("getAllNets get data: " + JSON.stringify(data));
if (data) {
GlobalContext.getContext().netList = data;
let itemNumber : Set<connection.NetHandle> = new Set(GlobalContext.getContext().netList);
let dataNumber = Array.from(itemNumber.values());
for (let item of dataNumber) {
// 循环获取网络列表每个netHandle对应网络的能力信息。
connection.getNetCapabilities(item).then((data: connection.NetCapabilities) => {
console.info("getNetCapabilities get data: " + JSON.stringify(data));
})
// 循环获取网络列表每个netHandle对应的网络的连接信息。
connection.getConnectionProperties(item).then((data: connection.ConnectionProperties) => {
console.info("getConnectionProperties get data: " + JSON.stringify(data));
})
}
}
})
// 引入包名。
import { connection } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';
// 使用默认网络解析主机名以获取所有IP地址。
connection.getAddressesByName("xxxx").then((data: connection.NetAddress[]) => {
console.info("Succeeded to get data: " + JSON.stringify(data));
});