我有一个应用程序,它反复从 API 获取一些数据。当我有 wifi 连接时,这真的很好。但是使用移动数据,我的请求要么超时,要么花费 20 秒。这没有意义,因为如果我只是在 android 浏览器中输入 API url,它几乎立即加载。另外,API 是一个非 s api 我不知道这是否重要。任何想法可能导致这一点?我的 Ktor 客户端:
object Ktor {
val ktor = Http(Android) {
install(DefaultRequest) {
header("apiKey", "apiKey")
}
install(ContentNegotiation) {
json()
}
defaultRequest {
contentType(ContentType.Application.Json)
accept(ContentType.Application.Json)
}
}
}
我的产品存储库:
object ProductRepository {
const val URL = "API"
const val LATEST_APK_URI = "$URL/apk"
suspend fun getProducts() = ktor.get("$URL/products").body<Map<String, List<ProductItem>>>().map {
it.key to it.value.sortedBy { item -> item.done }
}.toMap()
}
我的视图模型:
class ProductViewModel : ViewModel() {
val productFlow = mutableStateMapOf<String, List<ProductItem>>()
val errorFlow = MutableStateFlow<Error?>(null)
val lastRefreshFlow = MutableStateFlow<DateTimeTz?>(null)
fun refreshProducts(context: Context) {
viewModelScope.launch {
kotlin.runCatching {
ProductRepository.getProducts()
}.onSuccess {
productFlow.clear()
productFlow.putAll(it)
lastRefreshFlow.value = DateTime.nowLocal()
//updateOrder(context)
context.cacheFile.updateCache(productFlow)
}.onFailure {
errorFlow.value = SilentError("Konnte Produkte nicht neu laden", it)
}
}
}
}

浏览器将额外的标头添加到请求中,这些标头由 DDOS 保护机制使用,这些机制通常会根据客户端的 IP 等各种条件延迟或简单地拒绝请求。有时,如果不在标头中指定主机名,您甚至无法向服务器 IP 发出请求 (大概是因为 IP 是执行 DDOS 过滤的服务器,而不是终端服务器)。可能是不信任移动的 IP / 您的宽带应用程序使用的 IP。
服务器 / 云比 webapp 的实际代码更可能导致延迟。尝试使用不同的移动来查看它们是否都导致延迟。还要检查实际的 IP 及其关联的国家 / 地区。使用traceroute查看请求中的延迟可能有助于您查明问题。
如果您使用的域不是原始 IP,您可能还需要检查 DNS 解析是否导致延迟,尽管它不太可能导致重大和重复的延迟,因为它会缓存查询。
最后但并非最不重要的检查您使用客户端的 HTTP 库,它可能会做一些奇怪的“优化”和请求排队,这可能会搞砸,特别是如果你改变连接,而应用程序运行(凌空已知会导致相当悲伤和缓存响应在其默认设置)。
这是奇怪的 DNS 不缓存域 / IP 对第一次查询后,以便后续查询更快,可能是关于域指示它不要。据我所知,你不能做很多关于 DNS 通过蜂窝,因为它是由管理,所以替代方法是定义和使用一个 with its own DNS。如果这似乎相当在顶部或不方便,你也可以尝试做一个direct DNS query在后续的应用程序中使用
您还可以查看finding current DNS in Android和sending a UDP DNS query
本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处
评论列表(41条)