文件下载场景,APP启动后首次网络切换(wifi-->4G)之后1min内,HarmonyOS 鸿蒙Next http.requestInStream(xxx)请求一致报错2300028

文件下载场景,APP启动后首次网络切换(wifi–>4G)之后1min内,HarmonyOS 鸿蒙Next http.requestInStream(xxx)请求一致报错2300028 场景:文件下载场景,APP冷启动之后,进行网络切换,将网络由WIFI–>4G流量;

问题描述:在WIFI第一次切换到4G时,1~3s左右可以检查到网络为4G。但是在切换1min左右的时间内,使用http.requestInStream(xxx)接口发起网络请求时,会报错2300028,此时requestInStream不可用。但是在网络切换1min后,再次进行网络切换时,http.requestInStream(xxx)表现正常,随后多次切换均表现正常。

核心网络请求代码如下:

private createOption(entity: HttpRequestEntity): http.HttpRequestOptions {
  let options: http.HttpRequestOptions = {
    method: http.RequestMethod.GET,
    usingCache: true,
    header: {
      'Range': 'bytes=' + entity.downloadSize + '-',
      'Connection': 'keep-alive',
      'Keep-Alive': 'timeout=' + 60000 + ', max=' + 1000
    },
    readTimeout: 3600000,
    connectTimeout: 10000,
    usingProxy: true
  };

  return options;
}
public sendRequest(entity: HttpRequestEntity, listener: IRequestListener) {
  if (this.state != DownloadRequestState.IDLE) {
    return;
  }
  let downloadError = new DownloadError(0, "");
  if (StringUtil.isEmpty(entity.url)) { // 非法url
    downloadError.code = SdkStatusCode.DOWNLOAD_INVALID_URL;
    downloadError.message = "request invalid url";
    listener.onFailed(downloadError);
    return;
  }

  let fullPath = entity.downloadDir + DownloadConstants.FILE_SEPARATOR + entity.localPath;
  let file: fs.File|null = DownloadFileUtil.createFileWithPath(fullPath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE | fs.OpenMode.APPEND);

  if (file == null) {
    DownloadLogger.error(DownloadRequest.TAG, `sendRequest file = null, path=${entity.path}`);
    downloadError.code = SdkStatusCode.DOWNLOAD_FILE_IO_ERROR;
    downloadError.message = "DownloadRequest create file failed";
    listener.onFailed(downloadError);
    return;
  }

  let option = this.createOption(entity);

  this.httpRequest.on("dataReceive", (data: ArrayBuffer) => {
    try {
      if (file != null) {
        fs.writeSync(file.fd, data);
      }
      entity.downloadSize += data.byteLength;
      listener.updateProgress(data.byteLength);
    } catch (e) {
      DownloadLogger.error(DownloadRequest.TAG, `sendRequest dataReceive errCode=${e.code}`)
      DownloadFileUtil.closeFileSafely(file);
      this.resetHttpRequest();
      // 文件写入发生IO错误
      let code: Any = e.code;
      if (code == HttpErrorCode.NO_SPACE) {
        // 磁盘空间不足
        downloadError.code = SdkStatusCode.DOWNLOAD_SPACE_NOT_ENOUGH;
        downloadError.message = "No Space";
      } else {
        downloadError.code = SdkStatusCode.DOWNLOAD_FILE_IO_ERROR;
        downloadError.message = "request write file error";
      }
    }
  });

  this.httpRequest.on("dataEnd", () => {
    DownloadLogger.debug(DownloadRequest.TAG, `sendRequest dataEnd`)
    if (entity.downloadSize == entity.size) {
      listener.onSuccess();
    } else {
      if (downloadError.code != 0) { // 写入过程中发生错误
        if (downloadError.code == HttpErrorCode.NO_SPACE) {
          // 错误&异常,暂停下载
          listener.onError(downloadError);
        } else {
          // 失败重试
          listener.onFailed(downloadError);
        }
      } else { // 完整性校验失败,暂停下载
        downloadError.code = SdkStatusCode.DOWNLOAD_INTEGRITY_VERIFICATION_FAILED;
        downloadError.message = "download integrity verification failed";
        listener.onError(downloadError);
      }
    }
    DownloadFileUtil.closeFileSafely(file);
    this.resetHttpRequest();
  })

  this.state = DownloadRequestState.RUNNING;
  listener.onStart();
  this.httpRequest.requestInStream(url.URL.parseURL(entity.url).toString(), option)
    .then(() => {
      DownloadLogger.debug(DownloadRequest.TAG, `sendRequest finished`);
      DownloadFileUtil.closeFileSafely(file);
    }).catch((err: BusinessError) => {
      DownloadLogger.error(DownloadRequest.TAG, `sendRequest exception path=${entity.path}, err=${err.code}`)
      switch (err.code) {
        case HttpErrorCode.OPERATION_TIMEOUT:
          downloadError.code = SdkStatusCode.DOWNLOAD_TIME_OUT;
          downloadError.message = "request download operation timeout";
          break;
        case HttpErrorCode.URL_ERROR:
          downloadError.code = SdkStatusCode.DOWNLOAD_INVALID_URL;
          downloadError.message = "request url error";
          break;
        default:
          downloadError.code = SdkStatusCode.DOWNLOAD_NETWORK_ERROR;
          downloadError.message = "request net error";
          break;
      }
      this.destroyRequest();
      listener.onFailed(downloadError);
      DownloadFileUtil.closeFileSafely(file);
  });
}

更多关于文件下载场景,APP启动后首次网络切换(wifi-->4G)之后1min内,HarmonyOS 鸿蒙Next http.requestInStream(xxx)请求一致报错2300028的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

然后其他一些特别的现象是:

  1. 在同样的操作下,如果WIFI连接了Charles代理,在APP冷启动之后首次WIFI切换到4G之后,http.requestInStream(xxx)表现是正常的,不会出现2300028错误
  2. APP冷启动之后,4G网络下进行下载,切换到WIFI,表现正常。随后任意进行网络切换也表现正常。

更多关于文件下载场景,APP启动后首次网络切换(wifi-->4G)之后1min内,HarmonyOS 鸿蒙Next http.requestInStream(xxx)请求一致报错2300028的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,http.requestInStream(xxx)请求报错2300028通常与网络环境切换后的连接问题有关。错误码2300028表示网络连接异常,可能是由于网络切换后,系统未及时更新网络状态或网络连接尚未稳定导致的。

具体来说,当从Wi-Fi切换到4G时,网络接口和路由表可能需要重新配置,这会导致短暂的网络不可用或连接不稳定。如果在此状态下发起HTTP请求,可能会因网络未完全恢复而触发该错误。

解决该问题的一种方法是在网络切换后增加延迟或重试机制,确保网络连接稳定后再发起请求。此外,可以通过监听网络状态变化事件,在网络恢复后再执行相关操作。

需要注意的是,鸿蒙Next的网络管理机制可能与Android或iOS有所不同,因此在处理网络切换时需特别关注鸿蒙系统的网络管理行为。

回到顶部