目录

通过预建连接提升HTTP传输性能

概述

从6.1.1(24)版本开始,新增支持预建连接功能。

发起一次HTTP/HTTPS请求一般需要先和目标服务器完成TCP握手和TLS握手(仅HTTPS)。后续请求如果能够复用已完成握手的连接,则可以直接收发数据,从而节省握手的耗时。Remote Communication Kit支持HTTP预建连接的能力。应用可以发起一次不进行数据传输的请求,使后续请求不再需要建立连接。

需要满足以下条件才能复用连接:

约束与限制

通过预建连接提升HTTP传输性能,支持Phone、PC/2in1、Tablet、Wearable、TV设备。从API版本26.0.1开始,新增支持Car设备。

使用预建连接能力(ArkTS)

import { rcp } from '@kit.RemoteCommunicationKit';

export async function startConnectionOnlyByRequest() {
  const session = rcp.createSession();
  const request = new rcp.Request('https://example.com', 'GET');
  request.connectOnly = true;

  const response = await session.fetch(request);
  console.info(`Request succeeded, statusCode is ${response.statusCode}`);

  // 此session可用于发起后续请求
}

当Request的connectOnly属性被设置为true时,即使已有连接,此请求也一定会建立一条新的连接。

使用预建连接能力(C++)

#include "RemoteCommunicationKit/rcp.h"
#include <stdio.h>
#include <thread>

void DataRequestCallback(void *userContext, Rcp_Response *response, uint32_t errCode) {
    printf("DataRequest callback, errCode: %u\n", errCode);
    if (response != nullptr) {
        printf("Data request succeeded, status code: %d\n", response->statusCode);
        response->destroyResponse(response);
    }
}

void dataTransRequest() {
    uint32_t errCode = 0;
    // 创建session
    Rcp_Session *session = HMS_Rcp_CreateSession(nullptr, &errCode);
    printf("create session end: %d\n", errCode);
    const char *kHttpServerAddress = "https://example.com";
    Rcp_Request *dataRequest = HMS_Rcp_CreateRequest(kHttpServerAddress);
    dataRequest->method = RCP_METHOD_GET;

    // 设置本次请求仅建立连接。
    errCode = HMS_Rcp_SetRequestConnectOnly(dataRequest, true);

    Rcp_ResponseCallbackObject callback = {DataRequestCallback, nullptr};

    errCode = HMS_Rcp_Fetch(session, dataRequest, &callback);
    printf("session fetch end: %d\n", errCode);

    // 等待结果,仅是等待异步调用完成,开发者可根据自己实际场景处理回调。
    std::this_thread::sleep_for(std::chrono::milliseconds(1000 * 3));

    // 请求完成后,清理request
    HMS_Rcp_DestroyRequest(dataRequest);

    // 此session在被close前可用于发起后续请求
    errCode = HMS_Rcp_CloseSession(&session);
    printf("HMS_Rcp_CloseSession end errCode: %d\n", errCode);
}

请求被设置为仅建立连接后,即使已有连接,此请求也一定会建立一条新的连接。

只有通过HMS_Rcp_Fetch接口发起的请求可以复用已有的连接;通过HMS_Rcp_FetchSync接口发起的请求不支持连接复用。

通过DefaultSession使用连接复用能力

不同的session之间不支持连接复用。可以通过默认session在同一个session上方便地发起请求。通过getDefaultSession(ArkTS)和HMS_Rcp_GetDefaultSession(C API)获得的默认session在系统内实际上是同一个session。

ArkTS:

import { rcp } from '@kit.RemoteCommunicationKit';

export async function startConnectionOnlyByRequest() {
  const defaultSession = rcp.getDefaultSession();
  const request = new rcp.Request('https://example.com', 'GET');
  request.connectOnly = true;

  const response = await defaultSession.fetch(request);
  console.info(`Request succeeded, statusCode is ${response.statusCode}`);

  // 可以在默认session上发起后续请求
}

C++:

#include <stdio.h>
#include <thread>
#include "RemoteCommunicationKit/rcp.h"

Rcp_Session *defaultSession = nullptr;

void DataRequestCallback(void *userContext, Rcp_Response *response, uint32_t errCode) {
    printf("DataRequest callback, errCode: %u\n", errCode);
    if (response != nullptr) {
        printf("Data request succeeded, status code: %d\n", response->statusCode);
        response->destroyResponse(response);
    }
}

void dataTransRequest() {
    uint32_t errCode = 0;
    // 获得默认session
    errCode = HMS_Rcp_GetDefaultSession(&defaultSession);

    printf("create session end: %d\n", errCode);
    const char *kHttpServerAddress = "https://example.com";
    Rcp_Request *dataRequest = HMS_Rcp_CreateRequest(kHttpServerAddress);
    dataRequest->method = RCP_METHOD_GET;
  
    Rcp_ResponseCallbackObject callback = {DataRequestCallback, nullptr};
    errCode = HMS_Rcp_Fetch(defaultSession, dataRequest, &callback);
    printf("defaultSession fetch end: %d\n", errCode);
    // 等待结果,仅是等待异步调用完成,开发者可根据自己实际场景处理回调。
    std::this_thread::sleep_for(std::chrono::milliseconds(1000 * 3));
    // 清理request
    HMS_Rcp_DestroyRequest(dataRequest);

    // 可以在默认session上发起后续请求

    // 当不再需要默认session时,使用HMS_Rcp_CloseSession释放对默认session的强引用
    errCode = HMS_Rcp_CloseSession(&defaultSession);
    printf("HMS_Rcp_CloseSession end errCode: %d\n", errCode);
}

系统内会自动维护一个默认session。应用的默认session会持有对系统内默认session的引用。当应用所有的默认session被回收后,系统内默认session将被关闭。

当应用再次获取默认session时,系统内会创建一个新的默认session。新创建的默认session无法复用之前的连接。如果需要默认session长期保持连接,应用应长期持有至少一个默认session对象。