网络访问(Socket/WebSocket/HTTP)

news2024/11/15 4:33:15

概述

HarmonyOS为用户提供了网络连接功能,具体由网络管理模块负责。通过该模块,用户可以进行Socket网络通滚、WebSocket连接、HTTP数据请求等网络通信服务。

  1. Socket网络通信:通过Socket(嵌套字)进行数据通信,支持的协议包括UDP核TCP
  2. WebSocket网络通信:利用WebSocket协议创建服务器和客户端之间的双全工共数据通信
  3. HTTP数据请求:利用超文本传输协议(HTTP)向服务器发起数据请求

需要注意的是,在使用网络管理模块提供的网络数据通信服务之前,用户需要根据具体的使用情况,向系统获取相应的使用权限。

权限名说明
ohos.permission.GET_NETWORK_INFO获取网络连接信息
ohos.permission.INTERNET允许程序打开网络嵌套字,进行网络连接

 网络通信基础

Socket通信

Socket(套接字)是数据传输网络中不同应用进程之间进行数据交换的端点。从网络协议栈的角度来看,Socket位于应用层和传输层之间。处于网络两端的不同应用层进程,通过Socket指定对方的地址并选择合适的传输层协议,最终实现数据通信。

一个Socket可以使用IP地址和端口号唯一确定。尽管不同表示方法使用的格式不尽一致,但大多数情况下,IP地址使用点分十进制表示,端口号为一个整数。例如给定主机IP地址为88.133.33.22,占用端口号为8030,则可以得到一个形如88.133.33.22:80302的Socket。进行数据通信的双方应用层进程通过Socket找到对方的应用层进程,从而实现数据的交换。

Socket不仅可以作为“地址”找到数据通信对方进程,还是网络间的编程接口,通过它可以根据需求从Internet协议簇中选择合适的运输层协议,实现进程间的数据交换。常用的Socket有流套接字、数据报套接字及原始套接字等。

  1. 流套接字使用传输层TCP(Transmission Control Protocol)进行数据传输,为用户提供面向连接的可靠字节流传输服务。也就是说,该服务所收发数据以字节为单位,在数据传输前建立收发端的连接,并保证所发送字节流按序、无差错、无重复到达接收方。再进行网络编程时,使用SOCK_STREAM指明使用流套接字
  2. 数据报嵌套字使用传输层UDP(USER Datagram Protocol)进行数据传输,为用户提供无连接的数据报传输服务。也就是说,该服务所收发数据以数据报为单位,在数据传输前不建立收发端的连接,另外,也不保证所发送的数据可靠地到达。在进行网络编程时,使用SOCK_DGRAM指明使用数据报套接字
  3. 原始套接字能够对未经内核处理的IP报文进行操作,而与之相对应,流套接字或数据报套接字只能访问相应协议处理后的报文(TCP和UDP)。在进行网络编程时,使用SOCK_RAW指明使用原始套接字。

进程之间通过网络进行通信时,大多采用客户/服务器(Client/Server,C/s)通信方法。一个采用了TCP(流套接字)的C/S通信,在开始有效数据传输前必须建立连接,建立连接的过程称为三次握手,其流程如下:

  1. 服务器必须通过socket方法创建套接字,通过bind方法绑定服务器IP地址和端口,并通过listen方法准备随时接受客户发来的创建连接请求,这个过程成为被动打开(Passive Open)。
  2. 客户端通过connet方法发送一个主动打开(Active Open)连接请求。这将导致客户端通过流套接字发送一个同步报文段(Synchronize Segment,SYN)。该报文段将告诉服务器客户端的初始字节序列号及对于客户端SYN报文段的确认。
  3. 服务器在接收到客户端发来的SYN报文段后,必须发送确认报文段(ACK)。该报文段携带服务器的初始字节序列号及对于客户端SYN报文段的确认。
  4. 客户端必须确认服务器的SYN报文段。 

一个TCP连接在监护玩有效数据后必须终止连接,TCP连接的终止过程如下:

  1. 通信双方中的任何一方(成为发起方)首先调用close()方法发起连接终止过程,该动作称为主动关闭(Active Close)。该动作将通过TCP连接发送一个终止报文段(FIN),表明本方将终止有效数据发送。
  2. 另一方(称为接收方)在接收到FIN报文段后执行所谓的被动关闭(Passive Close)。接收的FIN报文段将被确认,并且该FIN报文段将通过文件结束符(end-of-life)通告应用层进程。
  3. 在接收到FIN保温一段时间后,接收方将通过close()方法关闭Socket,并通过TCP链接发送自己的FIN报文段。
  4. 发起方收到对方的FIN报文段,并将确认报文发给对方。 

 根据套接字提供的服务类型,可以将套接字所提供的服务分为面向连接的服务和无连接的服务,其中流套接字为面向连接的服务,而数据报套接字为无连接的服务。用户可以根据具体应用需求采用不同的服务/

面向连接的服务主要有以下特点:

  1. 在有效数据交互前,必须创建通信双方之间的连接;在有效数据交互间,必须维护连接;在有效数据交互后,必须终止并释放连接。
  2. 由于有效数据在连接后进行交互,所以各报文段无需携带目的地址。
  3. 可以确保数据的按序、无差错、无重复传输。
  4. 由于协议较为复杂,所以开销较大。

无连接的服务主要有以下特点:

  1. 在有效数据交互前,无须建立通信双方之间的连接。
  2. 每个数据报必须提供详细的目的主机地址及目的端口号。
  3. 数据可能出现时序、重复、丢失等后果。
  4. 协议简单,通信开销较小。 

WebSocket 通信

2011年IETF通过了WebSocket通信协议,即REC 6455标准,随后又通过RFC 7936文件补充。同时,WebSocket也是W2C的标准,并引入HTML5.WebSocket的协议名称为ws,WebSocket的出现较好地解决了Http的以下缺点:

  1. HTTP为无状态协议,服务器无法预知下次通信对方的身份,难以做出预先准备,这对一些应用(尤其实时通信)来讲是一种难以逾越的阻碍。
  2. 每次客户端发送HTTP请求时都需要携带较长的头部信息,这样服务器才能做出相应响应。这些重复的头部信息浪费大量贷款,并且也由于需要解析而耗费时间。
  3. HTTP难以实现信息的主动推送,一般情况下只能采用轮询及长连链接等方法实现,这样会大量浪费服务器资源。

与HTTP类似,WebSocket也是一种基于TCP实现的网络通信协议。另外,WebSocket也是一种应用层协议。但是,相较于HTTP,WebSocket具有以下优点:

  1. WebSocket类似于Socket通信,是一种全双工通信技术,即服务器和客户端都可以率先向对方发送信息,而HTTP只能由客户端先发送数据请求,服务器只有接收到请求后才能做出响应,因此,WebSocket具有更高的实时性。
  2. WebSocket制定了二进制帧,因此,相较于HTTP,WebSocket能够更好地支持二进制数据
  3. WebSocket支持用户协议扩展,即用户可以根据需要定义自己的子协议laikuozhanWebSocket。例如,用户可以通过自定义压缩协议来取得更为理想的压缩效果。
  4. WebSocket是一种状态协议,具有更小的通信开销。一经连接,WebSocket的数据帧中用于协议控制的头部信息十分少。在不包括扩展时,服务器到客户端的数据帧中头部只有2~10字节,从而客户端到服务器的数据帧中,头部只需额外加入4字节的掩码,而HTTP每个报文都需要添加冗长的头部信息,因此,WebSocket可以较好地节省带宽资源。 

WebSocket在传输有效数据之前,首先需要建立服务器与客户端之间的连接。在建立连接时,WebSocket复用HTTP协议传输报文,基本过程如下:

  1.  客户端利用HTTP大宋请求。该请求使用HTTP报文格式,在首部表示要进行协议升级,并且要升级为WebSocket协议。
  2. 服务器接收到客户端发来的协议升级请求后,通过HTTP报文格式返回状态码101表示同意协议升级。
  3. 客户端接收到返回报文后,连接成功建立。在此后的通信中,客户端和服务器之间将通过TCP开始全双工通信,通信数据的单位为数据帧。

在客户端发给服务器的数据帧中,需要额外加入4字节的数据掩码,其主要目的是提高WebSocket的通信安全。

HTTP通信 

HTTP一般采用浏览器/服务器(Browser?server,B/S)架构进行通信,同样也是一个应用层协议。它基于运输层TCP协议传输数据,并采用了简洁的请求-响应方式进行交互,即客户端根据自身需求将相应的请求发送至服务器,而服务器只能根据接收的客户端请求发送响应数据。另外,HTTP协议是一种无状态协议,不会在服务器端保留客户端数据,因此HTTP的模型非常简单,便于开发、部署。

经过多年发展,HTTP演进了4个版本,分别是0.9、1.0、1.1及2.0。

1991年0.9版本发布,该版本协议极为简单,是一个单行且只有GET方法的协议,并且服务器响应完请求后立即断开TCP连接

1996年1.0版本发布,该版本协议大大扩充了HTTP各项内容,但是该版本不是官方版本。支持的方法扩充为GET、HEAD和POST共三个。同时,增加了若干术语,其中最为显著的改进是增加状态码、传输内容不再限于纯文本字符串、数据报文添加头部。

1997年,HTTP1.1作为标准版本发布。该版本支持多达7种方法,并增加了多个术语。相较于HTP1.0,有扩充多个功能,如单IP支持多个域、流水线功能、持久连接、支援缓存等。HTTP1.1是一个长期稳定版本,目前有在该版本上扩展了支持加密交互的HTTPS协议。

2015年HTTP2.0作为规范发布,该版本协议聚焦于网络资源使用效率提升及降低时延感知。另外,该版本协议并不向下兼容之前的1.x协议。

其实,已有HTTP3.0版本,但其目前只是草案状态,并未正式成为标准。该版本协议旨在成为更快、更安全、更可靠的适用于各种设备的通信协议。

HTTP通过统一资源定位器(Uniform Resource Locator,URL)指定所需资源位置,一个HTTP事务包括来自客户端的请求,以及服务器对请求的响应。双方的通信以HTTP报文的形式进行交互。从客户端发送到服务器的报文称为请求报文,而从服务器到客户端的报文称为响应报文。请求报文与响应报文的格式十分近似,他们都包括三部分。

  1. 请求行(响应报文中的状态行):提示是何种请求或响应状态。
  2. 通用信息头:零或多个紧挨着请求行/状态行的域。每个域由一对名字和数值构成,并由冒号“:”隔开。通用信息头由一个空行结束。
  3. 包体:=】
  4. 在请求报文中,包体包含客户端发送给服务器的数据,而在响应报文中,携带服务器发送给客户端的响应数据。与请求行/状态行及通用信息头不同,包体可以是任何形式的二进制数据。

HTTP基于TCP/IP协议簇进行通信。HTTP客户端在向服务器发送消息之前,使用IP地址及端口号(Socket)在客户端和服务器之间建立连接。在TCP建立连接前,需要服务器的IP地址和端口号与服务器上运行的程序关联。

利用URL获取HTTP服务器的IP地址,URL是用来定位万维网中资源的地址,因此,它包含了提供该资源的主机的IP地址,同时也包括该主机会在哪个端口上等待客户端。一般情况下,Web服务器默认使用80端口提供服务,URL中的80端口可以省略不写。如果使用其他端口,如8080端口,则URL中也不能省略端口号。

通过IP地址和端口号,客户端可以轻松地通过TCP/IP进行通信。具体步骤如下:

  1. 客户端从URL中提取服务器的主机名
  2. 客户端将服务器的主机名转换为服务器的IP地址
  3. 客户端从URL中提取端口号
  4. 客户端与Web服务器建立TCP连接
  5. 客户端向服务器发送HTTP请求信息
  6. 服务器将HTTP响应发送回浏览器
  7. 连接关闭后,浏览器将显示解析的文档

实际开发 

Socket连接

Socket连接方式分为UDP和TCP两种协议,但无论是用哪种协议之前都需要导入Networkkit模块

导入模块

import { socket } from '@kit.NetworkKit';

UDP协议

socket.constructUDPSocketInstance

该模块用于创建一个UDPSocket对象,后续所有开发都要基于UDPSocket对象来进行

接口结构:

constructUDPSocketInstance(): UDPSocket

示例 
import { socket } from '@kit.NetworkKit';
let udp: socket.UDPSocket = socket.constructUDPSocketInstance();
bind

绑定IP地址和端口,端口可以指定或由系统随机分配。使用callback方式或Promise方式这两种方式作为异步方法,这里展示callback方式。

接口结构:

bind(address: NetAddress, callback: AsyncCallback<void>): void

示例
import { socket } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';

let udp: socket.UDPSocket = socket.constructUDPSocketInstance();
let bindAddr: socket.NetAddress = {
  address: '192.168.xx.xxx',
  port: 1234
}
udp.bind(bindAddr, (err: BusinessError) => {
  if (err) {
    console.log('bind fail');
    return;
  }
  console.log('bind success');
});
send

通过UDPSocket连接发送数据。使用callback方式或Promise方式作为异步方法,这里只展示callback方式。

接口结构:

send(options: UDPSendOptions, callback: AsyncCallback<void>): void

示例
import { socket } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';

let udp: socket.UDPSocket = socket.constructUDPSocketInstance();
let netAddress: socket.NetAddress = {
  address: '192.168.xx.xxx',
  port: 8080
}
let sendOptions: socket.UDPSendOptions = {
  data: 'Hello, server!',
  address: netAddress
}
udp.send(sendOptions, (err: BusinessError) => {
  if (err) {
    console.log('send fail');
    return;
  }
  console.log('send success');
});
close

关闭UDPSocket连接。使用callback方式或Promise方式作为异步方法,这里使用callback方式展示。

接口结构:

close(callback: AsyncCallback<void>): void

示例
import { socket } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';

let udp: socket.UDPSocket = socket.constructUDPSocketInstance();
udp.close((err: BusinessError) => {
  if (err) {
    console.log('close fail');
    return;
  }
  console.log('close success');
})
 getState

获取UDPSocket状态。使用callback方式或Promise方式作为异步方法,这里使用callbak方式展示。

接口结构:

getState(callback: AsyncCallback<SocketStateBase>): void

示例
import { socket } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';

let udp: socket.UDPSocket = socket.constructUDPSocketInstance();
let bindAddr: socket.NetAddress = {
  address: '192.168.xx.xxx',
  port: 8080
}
udp.bind(bindAddr, (err: BusinessError) => {
  if (err) {
    console.log('bind fail');
    return;
  }
  console.log('bind success');
  udp.getState((err: BusinessError, data: socket.SocketStateBase) => {
    if (err) {
      console.log('getState fail');
      return;
    }
    console.log('getState success:' + JSON.stringify(data));
  })
})

TCP协议

socket.constructTCPSocketInstance

创建一个TCPSocket对象,后续所有与服务器通信的操作都要围绕创建的TCPSocket对象展开

接口结构:

constructTCPSocketInstance(): TCPSocket

示例
import { socket } from '@kit.NetworkKit';
let tcp: socket.TCPSocket = socket.constructTCPSocketInstance();
bind

绑定IP地址和端口,端口可以指定为0由系统随机分配或指定为其它非0端口。使用callback方法或Promise方法作为异步方法,这里展示callback方法。

接口结构:

bind(address: NetAddress, callback: AsyncCallback<void>): void

示例
import { socket } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';

let tcp: socket.TCPSocket = socket.constructTCPSocketInstance();
let bindAddr: socket.NetAddress = {
  address: '192.168.xx.xxx',
  port: 8080
}
tcp.bind(bindAddr, (err: BusinessError) => {
  if (err) {
    console.log('bind fail');
    return;
  }
  console.log('bind success');
})
 connect

连接到指定的IP地址和端口。使用callback方法或Promise方法作为异步方法,这里展示callback方法。

接口结构:

connect(options: TCPConnectOptions, callback: AsyncCallback<void>): void

示例
import { socket } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';

let tcp: socket.TCPSocket = socket.constructTCPSocketInstance();
let netAddress: socket.NetAddress = {
  address: '192.168.xx.xxx',
  port: 8080
}
let tcpconnectoptions: socket.TCPConnectOptions = {
  address: netAddress,
  timeout: 6000
}
tcp.connect(tcpconnectoptions, (err: BusinessError) => {
  if (err) {
    console.log('connect fail');
    return;
  }
  console.log('connect success');
})
send

通过TCPSocket连接发送数据。使用callback方式或Promise方式作为异步方法,这里展示callback方式。

接口结构:

send(options: TCPSendOptions, callback: AsyncCallback<void>): void

示例
import { socket } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';

let tcp: socket.TCPSocket = socket.constructTCPSocketInstance();
let netAddress: socket.NetAddress = {
  address: '192.168.xx.xxx',
  port: 8080
}
let tcpconnectoptions: socket.TCPConnectOptions = {
  address: netAddress,
  timeout: 6000
}
tcp.connect(tcpconnectoptions, () => {
  console.log('connect success');
  let tcpSendOptions: socket.TCPSendOptions = {
    data: 'Hello, server!'
  }
  tcp.send(tcpSendOptions, (err: BusinessError) => {
    if (err) {
      console.log('send fail');
      return;
    }
    console.log('send success');
  })
})
close

关闭TCPSocket连接。使用callback方式或Promise方式作为异步方法,这里展示callback方式。

接口结构:

close(): Promise<void>

示例
import { socket } from '@kit.NetworkKit';

let tcp: socket.TCPSocket = socket.constructTCPSocketInstance();

tcp.close().then(() => {
  console.log('close success');
}).catch((err: BusinessError) => {
  console.log('close fail');
});

WebSocket连接

使用WebSocket建立服务器与客户端的双向连接,需要先通过createWebSocket方法创建WebSocket对象,然后通过connect方法连接到服务器。

当连接成功后,客户端会收到open事件的回调,之后客户端就可以通过send方法与服务器进行通信。

当服务器发信息给客户端时,客户端会收到message事件的回调。当客户端不要此连接时,可以通过调用close方法主动断开连接,之后客户端会收到close事件的回调。

若在上述任一过程中发生错误,客户端会收到error事件的回调。

导入模块

import { webSocket } from '@kit.NetworkKit';

 webSocket.createWebSocket

创建一个WebSocket,里面包括建立连接、关闭连接、发送数据和订阅/取消订阅WebSocket连接的打开事件、接收到服务器消息事件、关闭事件和错误事件。

接口结构:

createWebSocket(): WebSocket

示例 
let ws: webSocket.WebSocket = webSocket.createWebSocket();

 connect

根据URL地址,建立一个WebSocket连接,使用callback方式或Promise方式作为异步方法,这里展示callback方式。

接口结构:

connect(url: string, callback: AsyncCallback<boolean>): void

示例 
import { webSocket } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';

let ws = webSocket.createWebSocket();
let url = "ws://";
ws.connect(url, (err: BusinessError, value: boolean) => {
  if (!err) {
    console.log("connect success");
  } else {
    console.log("connect fail, err:" + JSON.stringify(err));
  }
});

 send

通过WebSocket连接发送数据,使用callback方式或Promise方式作为异步方法,这里展示callback方式。

接口结构:

send(data: string | ArrayBuffer, callback: AsyncCallback<boolean>): void

示例 
import { webSocket } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';

let ws = webSocket.createWebSocket();
let url = "ws://"
class OutValue {
  status: number = 0
  message: string = ""
}
ws.connect(url, (err: BusinessError, value: boolean) => {
    if (!err) {
      console.log("connect success");
    } else {
      console.log("connect fail, err:" + JSON.stringify(err))
    }
});
ws.on('open', (err: BusinessError, value: Object) => {
  console.log("on open, status:" + (value as OutValue).status + ", message:" + (value as OutValue).message);
    ws.send("Hello, server!", (err: BusinessError, value: boolean) => {
    if (!err) {
      console.log("send success");
    } else {
      console.log("send fail, err:" + JSON.stringify(err))
    }
  });
});

close

关闭WebSocket连接,使用callback方式或Promise方式作为异步方法,这里展示callback方式。

接口结构:

close(callback: AsyncCallback<boolean>): void

示例
import { webSocket } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';

let ws = webSocket.createWebSocket();
ws.close((err: BusinessError) => {
  if (!err) {
    console.log("close success")
  } else {
    console.log("close fail, err is " + JSON.stringify(err))
  }
});

close(可选参数code和reason)

根据可选参数code和reason,关闭WebSocket连接,使用callback方式作为异步方法。

接口结构:

close(options: WebSocketCloseOptions, callback: AsyncCallback<boolean>): void

示例
import { webSocket } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';

let ws = webSocket.createWebSocket();

let options: webSocket.WebSocketCloseOptions | undefined;
if (options != undefined) {
    options.code = 1000
    options.reason = "your reason"
}
ws.close(options, (err: BusinessError) => {
    if (!err) {
        console.log("close success")
    } else {
        console.log("close fail, err is " + JSON.stringify(err))
    }
});

HTTP数据请求

导入模块

import { http } from '@kit.NetworkKit';

完整示例

// 引入包名
import { http } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';

// 每一个httpRequest对应一个HTTP请求任务,不可复用
let httpRequest = http.createHttp();
// 用于订阅HTTP响应头,此接口会比request请求先返回。可以根据业务需要订阅此消息
// 从API 8开始,使用on('headersReceive', Callback)替代on('headerReceive', AsyncCallback)。 8+
httpRequest.on('headersReceive', (header: Object) => {
  console.info('header: ' + JSON.stringify(header));
});

httpRequest.request(// 填写HTTP请求的URL地址,可以带参数也可以不带参数。URL地址需要开发者自定义。请求的参数可以在extraData中指定
  "EXAMPLE_URL",
  {
    method: http.RequestMethod.POST, // 可选,默认为http.RequestMethod.GET
    // 当使用POST请求时此字段用于传递请求体内容,具体格式与服务端协商确定
    extraData: 'data to send',
    expectDataType: http.HttpDataType.STRING, // 可选,指定返回数据的类型
    usingCache: true, // 可选,默认为true
    priority: 1, // 可选,默认为1
    // 开发者根据自身业务需要添加header字段
    header: { 'Accept' : 'application/json' },
    readTimeout: 60000, // 可选,默认为60000ms
    connectTimeout: 60000, // 可选,默认为60000ms
    usingProtocol: http.HttpProtocol.HTTP1_1, // 可选,协议类型默认值由系统自动指定
    usingProxy: false, //可选,默认不使用网络代理,自API 10开始支持该属性
    caPath: '/path/to/cacert.pem', // 可选,默认使用系统预设CA证书,自API 10开始支持该属性
    clientCert: { // 可选,默认不使用客户端证书,自API 11开始支持该属性
      certPath: '/path/to/client.pem', // 默认不使用客户端证书,自API 11开始支持该属性
      keyPath: '/path/to/client.key', // 若证书包含Key信息,传入空字符串,自API 11开始支持该属性
      certType: http.CertType.PEM, // 可选,默认使用PEM,自API 11开始支持该属性
      keyPassword: "passwordToKey" // 可选,输入key文件的密码,自API 11开始支持该属性
    },
    certificatePinning: [ // 可选,支持证书锁定配置信息的动态设置,自API 12开始支持该属性
      {
        publicKeyHash: 'Pin1', // 由应用传入的证书PIN码,自API 12开始支持该属性
        hashAlgorithm: 'SHA-256' // 加密算法,当前仅支持SHA-256,自API 12开始支持该属性
      }, {
        publicKeyHash: 'Pin2', // 由应用传入的证书PIN码,自API 12开始支持该属性
        hashAlgorithm: 'SHA-256' // 加密算法,当前仅支持SHA-256,自API 12开始支持该属性
      }
    ]
    multiFormDataList: [ // 可选,仅当Header中,'content-Type'为'multipart/form-data'时生效,自API 11开始支持该属性
      {
        name: "Part1", // 数据名,自API 11开始支持该属性
        contentType: 'text/plain', // 数据类型,自API 11开始支持该属性
        data: 'Example data', // 可选,数据内容,自API 11开始支持该属性
        remoteFileName: 'example.txt' // 可选,自API 11开始支持该属性
      }, {
        name: "Part2", // 数据名,自API 11开始支持该属性
        contentType: 'text/plain', // 数据类型,自API 11开始支持该属性
        // data/app/el2/100/base/com.example.myapplication/haps/entry/files/fileName.txt
        filePath: `${getContext(this).filesDir}/fileName.txt`, // 可选,传入文件路径,自API 11开始支持该属性
        remoteFileName: 'fileName.txt' // 可选,自API 11开始支持该属性
      }
    ]
  },
  (err: BusinessError, data: http.HttpResponse) => {
    if (!err) {
      // data.result为HTTP响应内容,可根据业务需要进行解析
      console.info('Result:' + JSON.stringify(data.result));
      console.info('code:' + JSON.stringify(data.responseCode));
      console.info('type:' + JSON.stringify(data.resultType));
      // data.header为HTTP响应头,可根据业务需要进行解析
      console.info('header:' + JSON.stringify(data.header));
      console.info('cookies:' + JSON.stringify(data.cookies)); // 自API version 8开始支持cookie
      // 取消订阅HTTP响应头事件
      httpRequest.off('headersReceive');
      // 当该请求使用完毕时,开发者务必调用destroy方法主动销毁该JavaScript Object。
      httpRequest.destroy();
    } else {
      console.info('error:' + JSON.stringify(err));
      // 取消订阅HTTP响应头事件
      httpRequest.off('headersReceive');
      // 当该请求使用完毕时,开发者务必调用destroy方法主动销毁该JavaScript Object。
      httpRequest.destroy();
    }
  });

request

根据URL地址,发起HTTP网络请求,使用callback方式或Promise方式作为异步方法

接口结构:

request(url: string, callback: AsyncCallback<HttpResponse>): void

示例
import { http } from '@kit.NetworkKit';

let httpRequest = http.createHttp();
httpRequest.request("EXAMPLE_URL", (err: Error, data: http.HttpResponse) => {
  if (!err) {
    console.info('Result:' + data.result);
    console.info('code:' + data.responseCode);
    console.info('type:' + JSON.stringify(data.resultType));
    console.info('header:' + JSON.stringify(data.header));
    console.info('cookies:' + data.cookies); // 自API version 8开始支持cookie
  } else {
    console.info('error:' + JSON.stringify(err));
  }
});

request(options)

根据URL地址和相关配置项,发起HTTP网络请求,使用callback方式作为异步方法。

接口结构:

request(url: string, options: HttpRequestOptions, callback: AsyncCallback<HttpResponse>):void

示例
import { http } from '@kit.NetworkKit';

class Header {
  public contentType: string;

  constructor(contentType: string) {
    this.contentType = contentType;
  }
}

let httpRequest = http.createHttp();
let options: http.HttpRequestOptions = {
    method: http.RequestMethod.POST, // 可选,默认为http.RequestMethod.GET
    // 当使用POST请求时此字段用于传递请求体内容,具体格式与服务端协商确定
    extraData: 'data to send',
    expectDataType: http.HttpDataType.STRING, // 可选,指定返回数据的类型
    usingCache: true, // 可选,默认为true
    priority: 1, // 可选,默认为1
    // 开发者根据自身业务需要添加header字段
    header: new Header('application/json'),
    readTimeout: 60000, // 可选,默认为60000ms
    connectTimeout: 60000, // 可选,默认为60000ms
    usingProtocol: http.HttpProtocol.HTTP1_1, // 可选,协议类型默认值由系统自动指定
    usingProxy: false, //可选,默认不使用网络代理,自API 10开始支持该属性
};

httpRequest.request("EXAMPLE_URL", options, (err: Error, data: http.HttpResponse) => {
  if (!err) {
    console.info('Result:' + data.result);
    console.info('code:' + data.responseCode);
    console.info('type:' + JSON.stringify(data.resultType));
    console.info('header:' + JSON.stringify(data.header));
    console.info('cookies:' + data.cookies); // 自API version 8开始支持cookie
  } else {
    console.info('error:' + JSON.stringify(err));
  }
});

destroy

中断请求任务。

接口结构:

destroy(): void

示例
import { http } from '@kit.NetworkKit';
let httpRequest = http.createHttp();

httpRequest.destroy();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1942900.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

iOS开发设计模式篇第一篇MVC设计模式

目录 1. 引言 2.概念 1.Model 1.职责 2.实现 3.和Controller通信 1.Contrller直接访问Model 2.通过委托(Delegate)模式 3.通知 4.KVO 4.设计的建议 2.View 1.职责 2.实现 3.和Controller通信 1. 目标-动作&#xff08;Target-Action&#xff09;模式 2…

matlab gui下的tcp client客户端编程框架

GUI界面 函数外定义全局变量 %全局变量 global TcpClient; %matlab作为tcpip客户端 建立连接 在“连接”按钮的回调函数下添加以下代码&#xff1a; global TcpClient;%全局变量 TcpClient tcpip(‘192.168.1.10’, 7, ‘NetworkRole’,‘client’); %连接到服务器地址和端…

免费【2024】springboot北京医疗企业固定资产管理系统的设计与实现

博主介绍&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…

Springboot项目打包成镜像、使用docker-compose启动

Springboot项目打包成镜像、使用docker-compose启动 1、创建一个boot项目 1、添加依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSch…

Adobe Dimension(DN)安装包软件下载

目录 一、软件简介 二、软件下载 三、注意事项 四、软件功能 五、常用快捷键 快捷键&#xff1a; 一、软件简介 Adobe Dimension&#xff08;简称DN&#xff09;是Adobe公司推出的一款三维设计和渲染软件。与一般的3D绘图软件相比&#xff0c;DN在操作界面和功能上有所不…

预防大于治疗!夏季脑血管疾病高发,应该注意什么?

夏日炎炎&#xff0c;虽然气温攀升带来了一抹活力&#xff0c;却也悄悄增加了心脑血管疾病的风险。高温、高湿的环境易使人体血管扩张&#xff0c;心率加快&#xff0c;血液黏稠度上升&#xff0c;对于中老年人及已有心脑血管疾病史的人群而言&#xff0c;更是需要格外警惕。因…

项目实战--C#实现图书馆信息管理系统

本项目是要开发一个图书馆管理系统&#xff0c;通过这个系统处理常见的图书馆业务。这个系统主要功能是&#xff1a;&#xff08;1&#xff09;有客户端&#xff08;借阅者使用&#xff09;和管理端&#xff08;图书馆管理员和系统管理员使用&#xff09;。&#xff08;2&#…

Cxx Primer-chap6

什么是函数&#xff1a;A function is a block of code with a name.&#xff1a;函数调用和返回&#xff1a;&#xff0c;实例&#xff1a;名字有作用域(visible)&#xff0c;对象有生命周期(exist)&#xff1a; &#xff0c;lifetime取决于object在哪定义和如何定义&#xff…

算法题目整合4

文章目录 122. 大数减法123. 滑动窗口最大值117. 软件构建124. 小红的数组构造125. 精华帖子126. 连续子数组最大和 122. 大数减法 题目描述 以字符串的形式读入两个数字&#xff0c;编写一个函数计算它们的差&#xff0c;以字符串形式返回。输入描述 输入两个数字&#xff…

FPGA DNA 获取 DNA_PORT

FPGA DNA DNA 是 FPGA 芯片的唯一标识&#xff0c; FPGA 都有一个独特的 ID &#xff0c;也就是 Device DNA &#xff0c;这个 ID 相当于我们的身份证&#xff0c;在 FPGA 芯片生产的时候就已经固定在芯片的 eFuse 寄存器中&#xff0c;具有不可修改的属性。在 xilinx 7series…

Adobe国际认证详解-职业发展规划指南

Adobe国际认证&#xff0c;又称为Adobe Certified Professional&#xff08;简称ACP&#xff09;&#xff0c;是Adobe公司CEO签发的权威国际认证体系。这一认证体系基于Adobe核心技术及岗位实际应用操作能力的测评&#xff0c;旨在为用户提供创意软件的专业认证。 Adobe国际认证…

win11 安装 Gradle以及通过Gradle 编译Spring boot 2.7.x源码

一、win11 安装Gradle(7.5.1)&#xff1a; 1.1、下载二进制包 Gradle下载页面 1.2、配置环境变量 变量名&#xff1a;GRADLE_HOME 变量值&#xff08;二进制包解压路径&#xff09;&#xff1a;D:\develop-tool\gradle-7.5.1 变量名&#xff1a;GRADLE_USER_HOME 变量值&a…

知识表示 | 利用 Protégé 软件构建小型本体

Hi&#xff0c;大家好&#xff0c;我是半亩花海。本项目旨在利用 Protg 软件构建小型本体&#xff0c;探索本体建模的实际应用&#xff0c;特别是应用本体与上层本体之间的关系继承与映射。我们将重点理解应用本体如何继承上层本体的关系&#xff0c;以及如何通过推理机制揭示实…

线性dp.

线性dp&#xff0c;在进行动态规划中&#xff0c;常以线性的形式表现出来。 我们仍用闫氏dp法来进行求解即可 一、状态表示&#xff1a;当前的状态所代表的含义以及能用几维的形式表现出来。包括①集合&#xff0c;②属性 二、状态计算&#xff1a;如何一步一步的将状态计算出…

Hostspot2.0网络是什么?

Hotspot 2.0是一种无线网络技术标准&#xff0c;它是由Wi-Fi联盟推出的&#xff0c;旨在改善公共Wi-Fi热点的用户体验&#xff0c;简化连接流程&#xff0c;提升安全性&#xff0c;并提供更好的漫游体验。Hotspot 2.0也被称为Passpoint&#xff08;Passpoint Release 2&#xf…

Go基础编程 - 12 -流程控制

流程控制 1. 条件语句1.1. if...else 语句1.2. switch 语句1.3. select 语句1.3.1. select 语句的通信表达式1.3.2. select 的基特性1.3.3. select 的实现原理1.3.4. 经典用法1.3.4.1 超时控制1.3.4.2 多任务并发控制1.3.4.3 监听多通道消息1.3.4.4 default 实现非堵塞读写 2. …

【全网首发】小红书最新引流法:轻松留联系方式卡片,直接上演无举报窗口

大家好&#xff01;我是闷声轻创&#xff01;根据最新消息小红书卡片可能会被禁止掉&#xff0c;这对我们的引流矩阵有真不小的冲击&#xff0c;毕竟小红书作为国内领​先的年轻人的生活分享社区&#xff0c;但上有政策下有对策&#xff0c;我今天发现了一个新的留V的方法&…

七天打造一套量化交易系统:Day2-量化交易策略基本模型及要点

七天打造一套量化交易系统&#xff1a;Day2-量化交易策略基本模型及要点 前期回顾趋势型策略模型原理收益分布重点&#xff1a;什么因素能改进策略&#xff08;截断亏损&#xff0c;让利润奔跑&#xff09;要点总结 均值回复型策略模型原理收益分布重点&#xff1a;避免大额亏损…

去掉roscore的python依赖概述

去掉roscore的python依赖概述 文章目录 去掉roscore的python依赖概述roscore有哪些功能思路关于rosmaster本身及其API的介绍 需要实现的核心API代码实现附录(网图) roscore有哪些功能 启动一个rosmaster节点 调用roslaunch在子进程中&#xff08;popen&#xff09;启动rosmast…

浪潮自研交换机系列常见问题处理

CN61108PC-V-H 不能PING通任何地址&#xff0c;也不能被PING 输入ip traceroute enable既可。注意视图 交换机通过console口远程登录至其他交换机&#xff0c;掉线后console口无法使用 例如有2台交换机A和B&#xff0c;在A交换机上插上console线登录后&#xff0c;在A通过SSH…