Unexpected behavior while measuring download time using okhttp eventListener on Android - retrofit2

This question is a continuation of https://github.com/square/okhttp/issues/6991
I hope everyone is fine. I'm using okhttp version 4.3.1. I'm trying to measure the download time for a file. For that I have used the following code:
val okHttpClientBuilder = OkHttpClient.Builder()
.connectTimeout(5, TimeUnit.MINUTES) // connect timeout
.writeTimeout(5, TimeUnit.MINUTES) // write timeout
.readTimeout(5, TimeUnit.MINUTES)
.eventListener(object : EventListener() {
override fun callStart(call: Call) {
val callTimeEnd = System.currentTimeMillis()
Log.v(TAG, "callTimeEnd: $callTimeEnd")
}
override fun callEnd(call: Call) {
val callTimeStart = System.currentTimeMillis()
Log.v(TAG, "callTimeEnd: $callTimeEnd")
}
})
It logged the following timestamps:
callStart: 1641622023750
callEnd: 1641622031159
and callEnd - callStart = ~7.4seconds. My device (Android 9.0) has downloading speed of 5 Mega bits per second. File size is 25 Mega Bytes. Ideally, downloading time should be ~40 seconds. Am I missing something or do the library is doing something under the hood?
Moreover, another device (Android 8.0) with downloading speed of 20 Mega bits per second is downloading the same file in ~ 10 seconds i.e., taking longer time than Android 9.0 device. Any pointer will be appreciated.

The issue was with the network to which the devices were connected. I had applied rate limits on WAN ports, but the server was connected to a router through ethernet and clients were connected via Wifi, therefore, the file was being served to clients using local network which operates on a high bandwidth i.e., router was operating on a 150 Mbps, slow mobile was 65 Mbps, and fast was 144 Mbps which turns out the time to download for slow and fast was ~5 seconds and ~3 seconds respectively. I moved the server to WAN port and it provided the desired results i.e., slow device rate limit set to 5 Mbps and it downloaded the 25 Mega bytes file in ~43 seconds.

Related

ESP32: BLE transmission speed is very slow

I am trying to build an Android app that interfaces with the ESP32 using BLE. I am using the RxBluetoothKotlin library from Vincent Masselis for the Android side. For the ESP32 side, I am using the default Kolban libraries that are included in the Arduino IDE. My phone is a OnePlus 5T and my ESP32 is a MH ET Live ESP32DevKIT. My Android app can be found here, and my ESP32 program here.
The whole system works pretty much perfectly for me in terms of pure functionality. That is to say, every button does what it's supposed to do, and I get the exact behaviour I had expected to get. However, the communication itself is very slow. Around 200 bytes/second. My test button in the Android app requests a bunch of text data from the ESP32, and displays this in a dialog. It also lists a number which represents the time between request and reception in milliseconds. Using this, I get around 2 seconds for 440 bytes of data. When I send less data, the time decreases approximately linearly with data size. 40 bytes of data will take around 200ms, and 20 bytes or under typically takes less than 100ms.
This seems rather slow to me. From what I understand, I should be able to at least get a few kilobytes per second. I have tried to check the speed using nRF Connect, but I get the same 2 seconds timespan for my data transfer. This suggests that the problem is not in my app, since I also have it with a completely different app. I also put the code in my main loop inside of callbacks instead (which I probably should have done in the first place), but this didn't change things at all. I have tried taking the microcontroller and my phone to a few different locations, hoping to eliminate interference. I have tried to mess with BLEDevice::setPower and BLEDevice::setMTU, as well as setting RxBluetoothGatt.requestMtu(500) on the Android side. Everything so far seems to have had little to no effect. The only thing that did anything, was adding the line "pServer->updatePeerMTU(0,500);" in my loop during the connection phase. This caused the first 23 bytes of data to be repeated whenever I pressed the test button in my app, and made the data transfer take about 3 seconds. If I'm lucky, I can get maybe a bit under 1.8 seconds for 440 bytes, but this is a very small change when I'm expecting an order of magnitude of difference, and might even be down to pure chance rather than anything I did.
Does anyone have an idea of how to increase my transfer speed?
The data transmission speed is mainly influenced by the Bluetooth LE connection interval (between 7.5 ms and 4 seconds) and is negotiated between the master (central unit) and the peripheral device. The master establishes a connection with a parameter set and the peripheral can propose to change this parameter set. In the end, however, the central unit decides which parameter set is to be used.
But the Bluetooth connection interval cannot be changed by an Android applications directly, which normally act as the central role. Instead it can request a connection priority which is known to have an influence on the connection interval.

BLE data transfer speed

I am trying to know what is the maximum data transfer speed between an Android mobile phone and a BLE peripheral.
Wikipedia indicates that this is "125 kbit/s โ€“ 1 Mbit/s โ€“ 2 Mbit/s" (https://en.wikipedia.org/wiki/Bluetooth_Low_Energy#Technical_details)
However, I tried to implement a POC, with a BLE peripheral sending 20-bytes notifications every 10 ms (which should lead to a data transfer speed of 16 kbit/s), and a mobile app subscribing to these notifications. I only get a fraction of the emitted notifications (10%, which is 1600 bit/s). If I increase the number of notifications sent, the number of notifications received does not increase (sometimes, it even decreases).
My tests were done using react-native-ble-plx for the mobile phone and react-native-ble-peripheral for the fake BLE peripheral.
How can I do to achieve a 1 Mbit/s data transfer speed with a BLE peripheral?
You cannot increase the BLE data transfer speed. However, you can request an increase of the Maximum Transmission Unit (MTU) i.e. the the largest packet size, specified in bytes that can be sent between your BLE center and peripheral:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
bluetoothGatt.requestMtu(mtu);
}
Then handle the response in your BluetoothGattCallback's
#Override
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
}

What is the minimum packet latency that can be achieved with classic bluetooth (2.1) devices?

I'm using RN42 (http://www.microchip.com/wwwproducts/en/RN42) bluetooth module at 115200 bauds (UART SSP mode) to send very small (1 - 20 byte) serial data messages between a computer and a ATMega328 MCU. I find that the latency for one message is somewhere around 60 - 100 ms. I would need 10 ms or less in my application. I'm wondering if this is even possible with bluetooth 2.1 devices.ยด
I know that theoretically bluetooth packets can be sent every 2 * 625 us from one end since 625 us is the frequency hopping interval. Also, one package will always have a minimum of 126 + payload bits. If we are sending 10 bytes (80 bits), the minimum latency based on 115200 baud rate should be (126+80)/115200*1000 + 2 * 0.625 = 3 ms. However, when I measure the latency with a test code, the minimum latency will not go below 60 ms. This suggests that the baud rate or the frequency hopping are not the dominant causes of latency and for some reason the packages are not sent at a maximum rate.
Does someone know if < 60 ms latency is technically possible with this setup and if so, how to achieve it?

How to make low latency for HLS live streaming?

I have setup the live-stream with Flash Media Live Encoder 3.2, adobe media server 5.0, and VideoJS for HTML5 Player. It is about 10-20 seconds delay after adjust the setting.
I have reading what Apple and Adobe mention about the delay 25 and 30 second? Is it possible to adjust the setting to low latency (About 2 second latency) or alternative solution for low latency Live Streaming that support mobile device?
Apple Site
Q 21. What is the latency?
Approximately 30 seconds, with recommended settings.
Adobe Site
HTTP Live Streaming for Apple iOS (HLS)
Page 25: Higher latency due to real-time fragmenting process (a minimum of 25 seconds should be expected).
Use a HLSMediaFileDuration that is a multiple of the keyframe interval and lower the keyframe interval.
The player needs at least 3 segments to start the playback, so you can use segments of 1s length with keyframes each second.
This has disadvantages as it increases the stream size due to more frequent keyframes, adds a lot of overhead and requires more frequent playlist refreshes thus increasing the number of HTTP requests.
https://helpx.adobe.com/adobe-media-server/dev/configure-dynamic-streaming-live-streaming.html

How much data can I send through a socket.emit?

So I am using node.js and socket.io. I have this little program that takes the contents of a text box and sends it to the node.js server. Then, the server relays it back to other connected clients. Kind of like a chat service but not exactly.
Anyway, what if the user were to type 2-10k worth of text and try to send that? I know I could just try it out and see for myself but I'm looking for a practical, best practice limit on how much data I can do through an emit.
As of v3, socket.io has a default message limit of 1 MB. If a message is larger than that, the connection will be killed.
You can change this default by specifying the maxHttpBufferSize option, but consider the following (which was originally written over a decade ago, but is still relevant):
Node and socket.io don't have any built-in limits. What you do have to worry about is the relationship between the size of the message, number of messages being send per second, number of connected clients, and bandwidth available to your server โ€“ in other words, there's no easy answer.
Let's consider a 10 kB message. When there are 10 clients connected, that amounts to 100 kB of data that your server has to push out, which is entirely reasonable. Add in more clients, and things quickly become more demanding: 10 kB * 5,000 clients = 50 MB.
Of course, you'll also have to consider the amount of protocol overhead: per packet, TCP adds ~20 bytes, IP adds 20 bytes, and Ethernet adds 14 bytes, totaling 54 bytes. Assuming a MTU of 1500 bytes, you're looking at 8 packets per client (disregarding retransmits). This means you'll send 8*54=432 bytes of overhead + 10 kB payload = 10,672 bytes per client over the wire.
10.4 kB * 5000 clients = 50.8 MB.
On a 100 Mbps link, you're looking at a theoretical minimum of 4.3 seconds to deliver a 10 kB message to 5,000 clients if you're able to saturate the link. Of course, in the real world of dropped packets and corrupted data requiring retransmits, it will take longer.
Even with a very conservative estimate of 8 seconds to send 10 kB to 5,000 clients, that's probably fine in chat room where a message comes in every 10-20 seconds.
So really, it comes down to a few questions, in order of importance:
How much bandwidth will your server(s) have available?
How many users will be simultaneously connected?
How many messages will be sent per minute?
With those questions answered, you can determine the maximum size of a message that your infrastructure will support.
Limit = 1M (By Default)
Use this example config to specify your custom limit for maxHttpBufferSize:
const io = require("socket.io")(server, {
maxHttpBufferSize: 1e8, pingTimeout: 60000
});
1e8 = 100,000,000 : that can be good for any large scale response/emit
pingTimeout : When the emit was large then it take time and you need increase pingtime too
Read more from Socket.IO Docs
After these setting, if your problem is still remaining then you can check related proxy web server configs, like client_max_body_size, limit_rate in
nginx (if u have related http proxy to socketIO app) or client/server Firewall rules.
2-10k is fine, there arn't any enforced limits or anything, it just comes down to bandwidth and practicality.. 10k is small though in the grand scheme of things so you should be fine if that's somewhat of an upper bound for you.

Resources