From 204392ecd3a9c9d287a4b40f5dba14fa601e3e01 Mon Sep 17 00:00:00 2001 From: YangSen-qn Date: Fri, 20 Nov 2020 16:14:27 +0800 Subject: [PATCH 01/21] add network status manager --- .../networkStatus/NetworkStatusManager.java | 208 ++++++++++++++++++ .../UploadServerNetworkStatus.java | 42 ++++ .../http/request/UploadRequestState.java | 18 ++ 3 files changed, 268 insertions(+) create mode 100644 library/src/main/java/com/qiniu/android/http/networkStatus/NetworkStatusManager.java create mode 100644 library/src/main/java/com/qiniu/android/http/networkStatus/UploadServerNetworkStatus.java diff --git a/library/src/main/java/com/qiniu/android/http/networkStatus/NetworkStatusManager.java b/library/src/main/java/com/qiniu/android/http/networkStatus/NetworkStatusManager.java new file mode 100644 index 000000000..c7b27b7d6 --- /dev/null +++ b/library/src/main/java/com/qiniu/android/http/networkStatus/NetworkStatusManager.java @@ -0,0 +1,208 @@ +package com.qiniu.android.http.networkStatus; + +import com.qiniu.android.storage.FileRecorder; +import com.qiniu.android.storage.Recorder; +import com.qiniu.android.utils.AsyncRun; +import com.qiniu.android.utils.Utils; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Date; +import java.util.Iterator; +import java.util.concurrent.ConcurrentHashMap; + +public class NetworkStatusManager { + + private static String kNetworkStatusDiskKey = "NetworkStatus:v1.0.0"; + + private boolean isHandlingNetworkInfoOfDisk = false; + private Recorder recorder; + private ConcurrentHashMap networkStatusInfo; + private static NetworkStatusManager networkStatusManager = new NetworkStatusManager(); + + public static NetworkStatusManager getInstance() { + networkStatusManager.asyncRecoverNetworkStatusFromDisk(); + return networkStatusManager; + } + + public NetworkStatus getNetworkStatus(String type) { + if (type == null || type.length() == 0) { + return null; + } + NetworkStatus status = networkStatusInfo.get(type); + if (status == null) { + status = new NetworkStatus(); + } + return status; + } + + public void updateNetworkStatus(String type, int speed) { + if (type == null || type.length() == 0) { + return; + } + NetworkStatus status = networkStatusInfo.get(type); + if (status == null) { + status = new NetworkStatus(); + networkStatusInfo.put(type, status); + } + status.setSpeed(speed); + + asyncRecordNetworkStatusInfo(); + } + + + public void updateNetworkStatus(String type, boolean supportHTTP3) { + if (type == null || type.length() == 0) { + return; + } + NetworkStatus status = networkStatusInfo.get(type); + if (status == null) { + status = new NetworkStatus(); + networkStatusInfo.put(type, status); + } + status.setSupportHTTP3(supportHTTP3); + + asyncRecordNetworkStatusInfo(); + } + + + // ---------- 持久化 ----------- + private void asyncRecordNetworkStatusInfo() { + synchronized (this) { + if (isHandlingNetworkInfoOfDisk) { + return; + } + isHandlingNetworkInfoOfDisk = true; + } + AsyncRun.runInBack(new Runnable() { + @Override + public void run() { + recordNetworkStatusInfo(); + isHandlingNetworkInfoOfDisk = false; + } + }); + } + + private void asyncRecoverNetworkStatusFromDisk() { + synchronized (this) { + if (isHandlingNetworkInfoOfDisk) { + return; + } + isHandlingNetworkInfoOfDisk = true; + } + AsyncRun.runInBack(new Runnable() { + @Override + public void run() { + recoverNetworkStatusFromDisk(); + isHandlingNetworkInfoOfDisk = true; + } + }); + } + + private void recordNetworkStatusInfo() { + + setupRecorder(); + + if (recorder == null || networkStatusInfo == null) { + return; + } + + JSONObject networkStatusInfoJson = new JSONObject(); + for (String key : networkStatusInfo.keySet()) { + NetworkStatus status = networkStatusInfo.get(key); + if (status != null) { + try { + networkStatusInfoJson.put(key, status.toJson()); + } catch (Exception ignored) { + } + } + } + recorder.set(kNetworkStatusDiskKey, networkStatusInfoJson.toString().getBytes()); + } + + private void recoverNetworkStatusFromDisk() { + + setupRecorder(); + + if (recorder == null || networkStatusInfo == null) { + return; + } + + byte[] networkStatusInfoData = recorder.get(kNetworkStatusDiskKey); + JSONObject networkStatusInfoJSON = null; + try { + networkStatusInfoJSON = new JSONObject(new String(networkStatusInfoData)); + } catch (Exception ignored) { + return; + } + + for (Iterator it = networkStatusInfoJSON.keys(); it.hasNext(); ) { + String key = it.next(); + try { + JSONObject statusJson = networkStatusInfoJSON.getJSONObject(key); + NetworkStatus status = NetworkStatus.statusFromJson(statusJson); + if (status != null) { + networkStatusInfo.put(key, status); + } + } catch (JSONException ignored) { + } + } + } + + + private synchronized void setupRecorder() { + if (recorder == null) { + try { + recorder = new FileRecorder(Utils.sdkDirectory() + "/NetworkInfo"); + } catch (Exception ignored) { + } + } + } + + public static class NetworkStatus { + + private int speed; + private long http3FrozenTimestamp; + + public boolean isSupportHTTP3() { + return http3FrozenTimestamp < (new Date()).getTime(); + } + + public void setSupportHTTP3(boolean supportHTTP3) { + http3FrozenTimestamp = new Date().getTime(); + } + + public int getSpeed() { + return speed; + } + + public void setSpeed(int speed) { + this.speed = speed; + } + + private JSONObject toJson() { + JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put("speed", speed); + jsonObject.put("http3FrozenTimestamp", http3FrozenTimestamp); + } catch (Exception ignored) { + } + return jsonObject; + } + + private static NetworkStatus statusFromJson(JSONObject jsonObject) { + if (jsonObject == null) { + return null; + } + + NetworkStatus status = new NetworkStatus(); + try { + status.speed = jsonObject.getInt("speed"); + status.http3FrozenTimestamp = jsonObject.getLong("http3FrozenTimestamp"); + } catch (Exception ignored) { + } + return status; + } + } +} diff --git a/library/src/main/java/com/qiniu/android/http/networkStatus/UploadServerNetworkStatus.java b/library/src/main/java/com/qiniu/android/http/networkStatus/UploadServerNetworkStatus.java new file mode 100644 index 000000000..bcf089767 --- /dev/null +++ b/library/src/main/java/com/qiniu/android/http/networkStatus/UploadServerNetworkStatus.java @@ -0,0 +1,42 @@ +package com.qiniu.android.http.networkStatus; + +import com.qiniu.android.http.serverRegion.UploadServer; +import com.qiniu.android.utils.Utils; + +public class UploadServerNetworkStatus { + + public static boolean isServerSupportHTTP3(UploadServer server) { + if (server == null) { + return false; + } + + String serverType = Utils.getIpType(server.getIp(), server.getHost()); + if (server == null) { + return false; + } + + NetworkStatusManager.NetworkStatus status = NetworkStatusManager.getInstance().getNetworkStatus(serverType); + return status.isSupportHTTP3(); + } + + public static UploadServer getBetterNetworkServer(UploadServer serverA, UploadServer serverB) { + if (serverA == null) { + return serverB; + } else if (serverB == null) { + return serverA; + } + + String serverTypeA = Utils.getIpType(serverA.getIp(), serverA.getHost()); + String serverTypeB = Utils.getIpType(serverB.getIp(), serverB.getHost()); + if (serverTypeA == null) { + return serverB; + } else if (serverTypeB == null) { + return serverA; + } + + NetworkStatusManager.NetworkStatus serverStatusA = NetworkStatusManager.getInstance().getNetworkStatus(serverTypeA); + NetworkStatusManager.NetworkStatus serverStatusB = NetworkStatusManager.getInstance().getNetworkStatus(serverTypeB); + + return serverStatusB.getSpeed() < serverStatusA.getSpeed() ? serverA : serverB; + } +} diff --git a/library/src/main/java/com/qiniu/android/http/request/UploadRequestState.java b/library/src/main/java/com/qiniu/android/http/request/UploadRequestState.java index c7f5b063c..81b1fbd0c 100644 --- a/library/src/main/java/com/qiniu/android/http/request/UploadRequestState.java +++ b/library/src/main/java/com/qiniu/android/http/request/UploadRequestState.java @@ -2,6 +2,8 @@ class UploadRequestState { + private boolean isUseOldServer; + private boolean isHTTP3; private boolean isUserCancel; boolean isUserCancel(){ @@ -11,4 +13,20 @@ boolean isUserCancel(){ void setUserCancel(boolean isUserCancel) { this.isUserCancel = isUserCancel; } + + public boolean isUseOldServer() { + return isUseOldServer; + } + + public void setUseOldServer(boolean useOldServer) { + isUseOldServer = useOldServer; + } + + public boolean isHTTP3() { + return isHTTP3; + } + + public void setHTTP3(boolean HTTP3) { + isHTTP3 = HTTP3; + } } From 21e46448244010869e127e4406c2d969268f4a9a Mon Sep 17 00:00:00 2001 From: YangSen-qn Date: Thu, 26 Nov 2020 11:51:53 +0800 Subject: [PATCH 02/21] get better host by network speed --- library/library.iml | 2 +- .../UploadServerNetworkStatus.java | 8 +-- .../http/request/HttpRegionRequest.java | 9 ++-- .../http/request/HttpSingleRequest.java | 50 ++++++++++++------- .../android/http/request/IUploadRegion.java | 2 +- .../http/request/UploadRequestState.java | 2 +- .../http/serverRegion/UploadDomainRegion.java | 50 +++++++++++++------ 7 files changed, 80 insertions(+), 43 deletions(-) diff --git a/library/library.iml b/library/library.iml index 0691bbdcd..cb7736c3c 100644 --- a/library/library.iml +++ b/library/library.iml @@ -20,7 +20,7 @@