BBANetworkProbeScheduler.h 5.52 KB
//
//  BBANetworkProbeScheduler.h
//  BBAAPIRequest
//
//  Created by chenjia09 on 2020/2/6.
//  Copyright © 2020 Baidu. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "BBAAPIReqUtils.h"
#import "BBABaseAPIRequest.h"

NS_ASSUME_NONNULL_BEGIN

/// Probe ErrorCodeList 声明
extern int const ProbeCheckOK;
extern int const ProbeSendDnsQueryError;
extern int const ProbeReceiveDnsQueryError;
extern int const ProbeDnsUnknownHostError;
extern int const ProbeDnsError;
extern int const ProbeDnsUDPSocketError;
extern int const ProbeDnsNoServer;
extern int const ProbePingGetDefaultGatewayError;
extern int const ProbePingInitICMPError;
extern int const ProbePingDestHostIsNullError;
extern int const ProbePingReadWriteError;
extern int const ProbePingLossRateError;

/// 网络诊断回调(外部主动调用)
typedef void(^NetQualityDiagnoseCallback)(BOOL isSuccess, BBAPingResultInfo *pingResult, BBADnsResultInfo *dnsResult);

/// 用户是否允许使用流量
typedef bool(^GetUserEnableBind4GStatus)(void);

/// SDT 探测线程队列名称
FOUNDATION_EXPORT NSString *const SDTQueueLabelName;

/// SDT 复合链路探测线程队列名称
FOUNDATION_EXPORT NSString *const SDTMultipathQueueLableName;

/// 调试日志前缀
FOUNDATION_EXPORT NSString *const SDTLogPrefix;

/// 复合链路调试日志前缀
FOUNDATION_EXPORT NSString *const SDTMultipathLogPrefix;

/// 向SDT探测队列派发任务
#ifndef bbaapirequest_dispatch_sdt_queue_async_safe
#define bbaapirequest_dispatch_sdt_queue_async_safe(block)\
    if (strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), SDTQueueLabelName.UTF8String) == 0) {\
        block();\
    } else {\
        dispatch_async([self sdtQueue], block);\
    }
#endif

/// 向SDT复合链路探测队列派发任务
#ifndef bbaapirequest_dispatch_sdt_multipath_queue_async_safe
#define bbaapirequest_dispatch_sdt_multipath_queue_async_safe(block)\
    if (strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), SDTMultipathQueueLableName.UTF8String) == 0) {\
        block();\
    } else {\
        dispatch_async([self sdtMultipathQueue], block);\
    }
#endif

/// 弱网感知之主动探测逻辑管理
@interface BBANetworkProbeScheduler : NSObject

/// 单例
+ (instancetype)sharedInstance;

/// 根据NSURLSessionTask的ttfb值按需触发探测
/// @param ttfb TTFB耗时ms
/// @param task NSURLSessionTask
/// @param from 业务请求来源
/// @param subFrom 业务请求子来源
/// @param bdTraceId TraceId
/// @param isBind 是否是绑定网卡发送的请求
/// @param isQuic 是否是QUIC请求
- (void)probeWithTTFB:(NSTimeInterval)ttfb task:(NSURLSessionTask *)task
                 from:(APIRequestFrom)from
              subFrom:(APIRequestSubFrom)subFrom
            bdTraceId:(NSString *)bdTraceId
               isBind:(BOOL)isBind
               isQuic:(BOOL)isQuic;

/// 根据NSURLSessionTask的成功或者失败按需触发探测
/// @param task NSURLSessionTask
/// @param success 请求是否成功
/// @param error 失败时对应的具体错误
/// @param ttfb TTFB耗时 ms
/// @param duration 耗时 ms
/// @param from 业务请求来源
/// @param subFrom 业务请求子来源
/// @param isBind 是否是绑定网卡发送的请求
/// @param isQuic 是否是QUIC请求
- (void)probeWithTask:(NSURLSessionTask *)task success:(BOOL)success error:(NSError * _Nullable)error
                 ttfb:(NSTimeInterval)ttfb
             duration:(NSTimeInterval)duration
                 from:(APIRequestFrom)from
              subFrom:(APIRequestSubFrom)subFrom
            bdTraceId:(NSString *)bdTraceId
               isBind:(BOOL)isBind
               isQuic:(BOOL)isQuic;

/// 根据APIRequest的TTFB值, 按需触发探测
/// @param apiRequest HTTP请求
- (void)probeTTFBWithRequest:(BBABaseAPIRequest *)apiRequest;

/// 根据失败的APIRequest请求, 按需触发探测
/// @param apiRequest HTTP请求
- (void)probeURLResponseFailWithRequest:(BBABaseAPIRequest *)apiRequest;

/// 根据成功的APIRequest请求, 按需触发探测
/// @param apiRequest HTTP请求
- (void)probeURLResponseSuccessWithRequest:(BBABaseAPIRequest *)apiRequest;

/// 是否重新开启Quic次数计数
/// @param isEnable 开启与否
- (void)setNetworkProbeQuicEnable:(BOOL)isEnable;

/// 返回探测所使用的单线程队列
- (dispatch_queue_t)sdtQueue;

/// 返回复合链路探测所使用得单线程队列
- (dispatch_queue_t)sdtMultipathQueue;

/// 当进入弱网状态时(SDT或者NQE), 进行日志记录或状态更新或联动
- (void)hasEnterWeakState;

/// 当离开弱网状态时(SDT或者NQE), 进行日志记录和状态更新或联动
- (void)hasLeaveWeakState;

/// 开启复合链路, 对4/5G质量进行探测
- (void)startMultipathProbe;

/// 复合链路功能开启且可以对4/5G探测正常工作
- (BOOL)multipathWorking;

/// 进入: WiFi连接状态 && 4/5G可用且好网状态
- (void)enterMobileGoodNetWhenWiFiConnecting;

/// 退出: WiFi连接状态 && 4/5G不可用或非好网状态
- (void)exitMobileGoodNetWhenWiFiConnecting;

@property (atomic, strong) NSMutableDictionary<NSString *, NSNumber *> *pingErrCode;
@property (atomic, strong) NSMutableDictionary<NSString *, NSNumber *> *dnsErrCode;
@property (atomic, strong) NSMutableDictionary<NSString *, NSNumber *> *dnsSubErrCode;
@property (nonatomic, strong, readonly) NSString *localDnsServerIpList; /* 局域网Local DNS IP 列表 */
@property (nonatomic, strong, readonly) NSString *localDnsServerIpUsed; /* 发起探测所使用的DNS IP */
@property (nonatomic, copy) GetUserEnableBind4GStatus getUserEnableBind4GStatus;
@end

NS_ASSUME_NONNULL_END