781flyingdutchman / background_downloader

Flutter plugin for file downloads and uploads
Other
165 stars 76 forks source link

[Question] about IOS NSURLSession.background limit #401

Closed bladeofgod closed 1 month ago

bladeofgod commented 1 month ago

Hello, i'm an android developer, and i recently read some article about Ios's NSURLSession-limit, and found out in URLSessionConfiguration.background way the httpMaximumConnectionsPerHost will limited at 6. So, i go checked your code and found it's used same function. I'm confuse if set maxConcurrentByHost or maxConcurrent on ios has will worked ? or , am I completely mistaken?

    static func createUrlSession() -> Void {
        if UrlSessionDelegate.urlSession != nil {
            return
        }
        let config = URLSessionConfiguration.background(withIdentifier: UrlSessionDelegate.sessionIdentifier)
        let defaults = UserDefaults.standard
        let storedTimeoutIntervalForResource = defaults.double(forKey: BDPlugin.keyConfigResourceTimeout) // seconds
        let timeOutIntervalForResource = storedTimeoutIntervalForResource > 0 ? storedTimeoutIntervalForResource : BDPlugin.defaultResourceTimeout
        os_log("timeoutIntervalForResource = %d seconds", log: log, type: .info, Int(timeOutIntervalForResource))
        config.timeoutIntervalForResource = timeOutIntervalForResource
        let storedTimeoutIntervalForRequest = defaults.double(forKey: BDPlugin.keyConfigRequestTimeout) // seconds
        let timeoutIntervalForRequest = storedTimeoutIntervalForRequest > 0 ? storedTimeoutIntervalForRequest : BDPlugin.defaultRequestTimeout
        os_log("timeoutIntervalForRequest = %d seconds", log: log, type: .info, Int(timeoutIntervalForRequest))
        config.timeoutIntervalForRequest = timeoutIntervalForRequest
        let proxyAddress = defaults.string(forKey: BDPlugin.keyConfigProxyAdress)
        let proxyPort = defaults.integer(forKey: BDPlugin.keyConfigProxyPort)
        if (proxyAddress != nil && proxyPort != 0) {
            config.connectionProxyDictionary = [
                kCFNetworkProxiesHTTPEnable: true,
                kCFNetworkProxiesHTTPProxy: proxyAddress!,
                kCFNetworkProxiesHTTPPort: proxyPort,
                "HTTPSEnable": true,
                "HTTPSProxy": proxyAddress!,
                "HTTPSPort": proxyPort
            ]
            os_log("Using proxy %@:%d for all tasks", log: log, type: .info, proxyAddress!, proxyPort)
        } else {
            os_log("Not using proxy for any task", log: log, type: .info)
        }
        UrlSessionDelegate.urlSession = URLSession(configuration: config, delegate: UrlSessionDelegate.instance, delegateQueue: nil)
    }
781flyingdutchman commented 1 month ago

In my experience the httpMaximumConnectionsPerHost property does not really work, as servers have different ways to implement this (and for example using HTTP/2 this is bypassed altogether, as multiple requests are carried over 1 connection). See for example this thread. The way I have implemented this is therefore on the client side, by counting the number of tasks that are active with a given host, and not scheduling new tasks if that number equals the maximum set - so I am not using httpMaximumConnectionsPerHost at all.

bladeofgod commented 1 month ago

In my experience the httpMaximumConnectionsPerHost property does not really work, as servers have different ways to implement this (and for example using HTTP/2 this is bypassed altogether, as multiple requests are carried over 1 connection). See for example this thread. The way I have implemented this is therefore on the client side, by counting the number of tasks that are active with a given host, and not scheduling new tasks if that number equals the maximum set - so I am not using httpMaximumConnectionsPerHost at all.

I see, thanks for your reply. :)