import { ArrayList, HashMap } from '@kit.ArkTS'; import http from '@ohos.net.http'; import { LogHelper } from '../../../../Index'; import { SZYXLocalStorageHelper } from '../utils/SZYXLocalStorageHelper'; import { SZYXLocalStorageKeys } from '../utils/SZYXLocalStorageKeys'; import { HttpHelperX, HttpParamsForm, HttpParamsGet, HttpParamsPost } from './HttpHelperX'; export class HttpHelper { private static instance: HttpHelper | null = null // 单例模式 static get() { // 判断系统是否已经有单例了 if (HttpHelper.instance === null) { HttpHelper.instance = new HttpHelper() } return HttpHelper.instance } //请求中队列 private httpHandlerList = new HashMap(); // 并发白名单,这个名单里面的api,重复请求不会取消 private concurrentList = new ArrayList(); constructor() { this.httpHandlerList = new HashMap(); SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerList, this.httpHandlerList) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerListLength, this.httpHandlerList.length) this.concurrentList.clear() } /** * 添加并发白名单 * @param apiNo */ public addConcurrent(apiNo?: string) { if (!apiNo) { return } if (this.concurrentList.getIndexOf(apiNo) === -1) { this.concurrentList.add(apiNo) } } public removeConcurrent(apiNo: string) { if (this.concurrentList.getIndexOf(apiNo) !== -1) { this.concurrentList.remove(apiNo) } } /** * postJson请求 * @param url url地址 * @param headers * @param apiNo 请求标识,取消请求或者去重使用|考虑做自动重试使用 * @returns */ public postJson(params: HttpParamsPost, apiNo?: string, showLog?: boolean): Promise { return new Promise((resolve, reject) => { if (this.concurrentList.getIndexOf(apiNo ?? params.url) === -1 && this.httpHandlerList.hasKey(apiNo ?? params.url)) { this.httpHandlerList.get(apiNo ?? params.url).destroy() this.httpHandlerList.remove(apiNo ?? params.url) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerList, this.httpHandlerList) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerListLength, this.httpHandlerList.length) } let httpRequest = http.createHttp(); if (this.concurrentList.getIndexOf(apiNo ?? params.url) === -1) { this.httpHandlerList.set(apiNo ?? params.url, httpRequest) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerList, this.httpHandlerList) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerListLength, this.httpHandlerList.length) } const header = HttpHelperX.getHeaders("application/json;charset=UTF-8", params.headers) if (showLog) { LogHelper.debug(`postJson:${apiNo}\n`, JSON.stringify(params)) } httpRequest.request(HttpHelperX.getUrl(params.url, params.query), { method: http.RequestMethod.POST, connectTimeout: 20000, readTimeout: 20000, header: header, extraData: params.data, usingCache: false, }) .then((data: http.HttpResponse) => { if (showLog) { LogHelper.debug(`${apiNo}:\n ${data.result as string}`) LogHelper.print(data) } if (this.httpHandlerList.hasKey(apiNo ?? params.url)) { this.httpHandlerList.remove(apiNo ?? params.url) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerList, this.httpHandlerList) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerListLength, this.httpHandlerList.length) } if (data.responseCode === 200) { resolve((typeof data.result === 'string' ? JSON.parse(data.result) : data.result) as T) } else { const err: Error = new Error() err.name = data.responseCode.toString() err.message = '服务异常' reject(err) } }).catch((err: Error) => { LogHelper.error(JSON.stringify({ err: err, url: params.url, })) if (this.httpHandlerList.hasKey(apiNo ?? params.url)) { this.httpHandlerList.remove(apiNo ?? params.url) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerList, this.httpHandlerList) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerListLength, this.httpHandlerList.length) } if (err.message === 'Failed writing received data to disk/application') { const error: Error = new Error() error.name = 'cancel' error.message = err.message reject(error) } else { reject(err) } }); }); } /** * postForm请求 * @param url url地址 * @param headers * @param apiNo 请求标识,取消请求或者去重使用|考虑做自动重试使用 * @returns */ public postForm(params: HttpParamsForm, apiNo?: string, showLog?: boolean): Promise { return new Promise((resolve, reject) => { if (this.concurrentList.getIndexOf(apiNo ?? params.url) === -1 && this.httpHandlerList.hasKey(apiNo ?? params.url)) { this.httpHandlerList.get(apiNo ?? params.url).destroy() this.httpHandlerList.remove(apiNo ?? params.url) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerList, this.httpHandlerList) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerListLength, this.httpHandlerList.length) } let httpRequest = http.createHttp(); if (this.concurrentList.getIndexOf(apiNo ?? params.url) === -1) { this.httpHandlerList.set(apiNo ?? params.url, httpRequest) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerList, this.httpHandlerList) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerListLength, this.httpHandlerList.length) } const header = HttpHelperX.getHeaders("application/x-www-form-urlencoded;charset=UTF-8", params.headers) let data = HttpHelperX.getContent(params.data) if (showLog) { LogHelper.debug(`postForm:${apiNo}\n`, JSON.stringify(params)) } httpRequest.request(HttpHelperX.getUrl(params.url, params.query), { method: http.RequestMethod.POST, connectTimeout: 20000, readTimeout: 20000, header: header, usingCache: false, extraData: data ? encodeURI(data) : undefined }) .then((data: http.HttpResponse) => { if (showLog) { LogHelper.debug(`${apiNo}:\n ${data.result as string}`) LogHelper.print(data) } if (this.httpHandlerList.hasKey(apiNo ?? params.url)) { this.httpHandlerList.remove(apiNo ?? params.url) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerList, this.httpHandlerList) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerListLength, this.httpHandlerList.length) } if (data.responseCode === 200) { resolve((typeof data.result === 'string' ? JSON.parse(data.result) : data.result) as T) } else { const err: Error = new Error() err.name = data.responseCode.toString() err.message = '服务异常' reject(err) } }).catch((err: Error) => { LogHelper.error(JSON.stringify({ err: err, url: params.url, })) if (this.httpHandlerList.hasKey(apiNo ?? params.url)) { this.httpHandlerList.remove(apiNo ?? params.url) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerList, this.httpHandlerList) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerListLength, this.httpHandlerList.length) } if (err.message === 'Failed writing received data to disk/application') { const error: Error = new Error() error.name = 'cancel' error.message = err.message reject(error) } else { reject(err) } }); }); } /** * get请求 * @param url url地址 * @param data 请求参数 * @param headers * @param apiNo 请求标识,取消请求或者去重使用|考虑做自动重试使用 * @returns */ public get(params: HttpParamsGet, apiNo?: string, showLog?: boolean): Promise { return new Promise((resolve, reject) => { if (this.concurrentList.getIndexOf(apiNo ?? params.url) === -1 && this.httpHandlerList.hasKey(apiNo ?? params.url)) { this.httpHandlerList.get(apiNo ?? params.url).destroy() this.httpHandlerList.remove(apiNo ?? params.url) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerList, this.httpHandlerList) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerListLength, this.httpHandlerList.length) } let httpRequest = http.createHttp(); if (this.concurrentList.getIndexOf(apiNo ?? params.url) === -1) { this.httpHandlerList.set(apiNo ?? params.url, httpRequest) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerList, this.httpHandlerList) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerListLength, this.httpHandlerList.length) } if (showLog) { LogHelper.debug(`GET:${apiNo}\n`, HttpHelperX.getUrl(params.url, params.query) + '\n', JSON.stringify(params.headers)) } httpRequest.request(HttpHelperX.getUrl(params.url, params.query), { method: http.RequestMethod.GET, connectTimeout: 20000, readTimeout: 20000, header: params.headers, usingCache: false, // extraData: params.data }) .then((data: http.HttpResponse) => { if (showLog) { LogHelper.debug(`${apiNo}:\n${data.result as string}`) LogHelper.print(data) } if (this.httpHandlerList.hasKey(apiNo ?? params.url)) { this.httpHandlerList.remove(apiNo ?? params.url) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerList, this.httpHandlerList) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerListLength, this.httpHandlerList.length) } if (data.responseCode === 200) { resolve((typeof data.result === 'string' ? JSON.parse(data.result) : data.result) as T) } else { const err: Error = new Error() err.name = data.responseCode.toString() err.message = '服务异常' reject(err) } }).catch((err: Error) => { LogHelper.error(JSON.stringify({ err: err, url: params.url, })) if (this.httpHandlerList.hasKey(apiNo ?? params.url)) { this.httpHandlerList.remove(apiNo ?? params.url) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerList, this.httpHandlerList) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerListLength, this.httpHandlerList.length) } if (err.message === 'Failed writing received data to disk/application') { const error: Error = new Error() error.name = 'cancel' error.message = err.message reject(error) } else { reject(err) } }); }); } clearHttp() { for (let handler of this.httpHandlerList.keys()) { this.cancel(handler) } } cancel(apiNo: string) { if (this.httpHandlerList.hasKey(apiNo)) { this.httpHandlerList.get(apiNo).destroy() this.httpHandlerList.remove(apiNo) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerList, this.httpHandlerList) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.HttpHandlerListLength, this.httpHandlerList.length) } } }