HTTP streaming allows the client and server to exchange data in a stream format without waiting for all the data to be ready, which can significantly improve user experience. This mode is suitable for scenarios such as uploading and downloading large files, live streaming, and real-time data updates.
The streaming capability supports phones, 2-in-1 devices, tablets, and wearables. Starting from version 5.1.1(19), it is also supported on TVs.
Import the required modules.
import { rcp } from '@kit.RemoteCommunicationKit';
import { BusinessError } from '@kit.BasicServicesKit'; Use rcp.NetworkInputQueue to create a synchronous write queue object to implement synchronous writing.
export const testNetworkInputQueue = () => {
// Create a synchronous write queue object.
const networkInputQueue = new rcp.NetworkInputQueue();
// Simulate the scenario where a file is uploaded using synchronous read/write streams and write the file to the synchronous write queue networkInputQueue.
let counter = 0;
const interval = setInterval(() => {
// Add data to the synchronous write queue.
networkInputQueue.write('a counter ' + counter++);
console.info(`networkInputQueue write`);
if (counter === 10) {
clearInterval(interval);
// Close the synchronous write queue.
networkInputQueue.close();
}
}, 1000);
try {
// Create a session.
const session = rcp.createSession();
console.info(`Post start.`);
// Initiate a request. 'https://httpbin.org/anything' is a sample URL. The data is uploaded as it is written to the networkInputQueue.
session.post('https://httpbin.org/anything', networkInputQueue).then((response) => {
// Result status code.
console.info(`Response status code is: ${response.statusCode}`);
// ...
if (response && response.statusCode === 200) {
console.info(`Post succeeded! response: ${response.toString()}`);
} else {
console.error(`Post failed.`);
}
session.close();
}).catch((err: BusinessError) => {
console.error(`Post error code is ${err.code}, error data is ${err.data}`);
// ...
session.close();
});
} catch (err) {
console.error(`create session error code is ${err.code}, error data is ${err.data}`);
// ...
}
} Use rcp.NetworkOutputQueue to create a synchronous read queue object to implement synchronous reading.
export const testNetworkOutputQueue = () => {
// Create a synchronous read queue object.
const networkOutputQueue = new rcp.NetworkOutputQueue();
// Create a session.
try {
const session = rcp.createSession();
// Configure the size of the request stream data.
const numOfChunks = 10;
const chunkLength = 1000;
const totalBytes = numOfChunks * chunkLength;
// Initiate a request. 'https://httpbin.org/bytes/' is a sample URL. The response data is temporarily stored in the synchronous read queue networkOutputQueue.
session.get('https://httpbin.org/bytes/' + totalBytes.toString(), networkOutputQueue).then((response) => {
// ...
if (response && response.statusCode === 200) {
console.info(`get bytes succeeded.`);
} else {
console.error(`get bytes failed.`);
}
session.close();
}).catch((err: BusinessError) => {
console.error(`get bytes error code is ${err.code}, error data is ${err.data}`);
// ...
session.close();
});
// Read data from the networkOutputQueue queue cyclically to retrieve response data. For example, read 1000 bytes of data every 1000 milliseconds.
let totalGetLength = 0;
const intervalId = setInterval(() => {
// Process the read data based on your service needs.
const chunk = networkOutputQueue.read(chunkLength);
totalGetLength += chunk.byteLength;
console.info(`get bytes totalGetLength: ${totalGetLength}`);
// Clear the timer after data reading is complete.
if (totalGetLength === totalBytes) {
clearInterval(intervalId);
console.info(`get bytes finished.`);
}
}, 1000);
} catch (err) {
console.error(`create session error code is ${err.code}, error data is ${err.data}`);
// ...
}
} For details about the APIs, please refer to the API Reference.
| API | Description |
|---|---|
| uploadFromStream(url: URLOrString, uploadFrom: UploadFromStream): Promise<Response> | Uploads data via streams. |
| downloadToStream(url: URLOrString, downloadTo: DownloadToStream): Promise<Response> | Downloads data via streams. |
Import the required modules.
import { rcp } from '@kit.RemoteCommunicationKit';
import { fileIo } from '@kit.CoreFileKit';
import { BusinessError } from '@kit.BasicServicesKit'; Define the FdReadStream class and implement the rcp.ReadStream API to read data from streams.
class FdReadStream implements rcp.ReadStream {
public readonly fd: number;
constructor(fd: number) {
this.fd = fd;
}
async read(buffer: ArrayBuffer): Promise<number> {
return fileIo.read(this.fd, buffer);
}
} Call the uploadFromStream API to upload data via streams.
export function testUploadFromStream(uploadFilePath: string) {
try {
// Create a session.
const session = rcp.createSession();
// Open the file based on the path of the file to be uploaded.
const file = fileIo.openSync(uploadFilePath, fileIo.OpenMode.READ_ONLY);
// File reading stream.
const fileStream = new rcp.UploadFromStream(new FdReadStream(file.fd));
// Upload data as a stream. 'https://httpbin.org/anything' is a sample URL.
session.uploadFromStream('https://httpbin.org/anything', fileStream).then((resp) => {
console.info(`testUploadFromStream response: ${JSON.stringify(resp.statusCode)}`);
// ...
if (resp && resp.statusCode === 200) {
console.info(`testUploadFromStream succeeded.`);
} else {
console.error(`testUploadFromStream failed.`);
}
}).catch((err: BusinessError) => {
console.error(`testUploadFromStream error code is ${err.code}, error data is ${err.data}`);
// ...
fileIo.closeSync(file.fd);
session.close();
}).finally(() => {
// Close the file and session after the upload is complete.
fileIo.closeSync(file.fd);
session.close();
});
} catch (err) {
console.error(`testUploadFromStream error code is ${err.code}, error data is ${err.data}`);
// ...
}
} Define the FdWriteStream class and implement the WriteStream API to write data via streams.
class FdWriteStream implements rcp.WriteStream {
public readonly fd: number;
constructor(fd: number) {
this.fd = fd;
}
async write(buffer: ArrayBuffer): Promise<number | void> {
return fileIo.write(this.fd, buffer);
}
} Call the downloadToStream API to download data via streams.
export function testDownloadToStream(downloadToPath: string) {
try {
// Create a session.
const session = rcp.createSession();
// Open the file based on the path of the file to be downloaded.
const file = fileIo.openSync(downloadToPath, fileIo.OpenMode.CREATE | fileIo.OpenMode.WRITE_ONLY);
// File writing stream.
const fileStream = { kind: 'stream', stream: new FdWriteStream(file.fd) } as rcp.DownloadToStream;
// Download data as a stream. 'https://httpbin.org/bytes/10000' is a sample URL.
session.downloadToStream('https://httpbin.org/bytes/10000', fileStream)
.then((resp) => {
console.info(`testDownloadToStream response: ${JSON.stringify(resp.statusCode)}`);
// ...
if (resp && resp.statusCode === 200) {
console.info(`testDownloadToStream succeeded.`);
} else {
console.error(`testDownloadToStream failed.`);
}
})
.catch((err: BusinessError) => {
console.error(`testDownloadToStream error code is ${err.code}, error data is ${err.data}`);
// ...
fileIo.close(file.fd);
session.close();
})
.finally(() => {
// Close the file and session after the upload is complete.
fileIo.closeSync(file.fd);
session.close();
});
} catch (err) {
console.error(`testDownloadToStream error code is ${err.code}, error data is ${err.data}`);
// ...
}
}