'Android native websocket libraries connect super slow or timeout on node.js ws server [closed]

I am trying to establish a websocket connection from an android smartphone to a node.js ws server. The server listens to port 8000 and has a secure wss connection. The problem occurs on Ktor Client, OkHttp and other apps that are able to connect to websockets. However, it does not occur on mobile browsers.

I can effortlessly establish a connection on the android studio emulator. I can also compile a debug apk, install it on a device (Android 9) and connect from there. This is where it starts to get weird. When I enable wifi on my device (Android 9), the creation of the connection takes about 10 seconds or times out. When using a vpn, the connection can be established instantly, even over wifi. The same behavior can be observed on another device (Android 10), but there, it even happens with mobile data. Another device (Android 12) doesn't experience these problems at all.

I have spent the last couple hours debugging but I just can't understand why this happens. The server logs show, that the connection request was never processed, so it was either never sent/sent super late from the device or blocked for a specific time server side. The problem also only happens with this server. It has to have something to do with how android sends wss requests and how the server processes it (maybe something certificate related?), I just don't know what.

Update: I have implemented X509TrustManager to check if the application works when the trust check is skipped. I placed a log inside the checkServerTrusted method and it is never called.

That isolates the problem to somewhere before the cert exchange.

Update 2: I have found the problem and it is DNS related. After further debugging, I have found out, that the connection is successfull if I directly connect to the IP. It seems like Android has a problem if the server has an IPv6 address and the network is configured to enable IPv6 SLAAC. The IPv6 lookup fails after about 10 seconds and if the client is able to recover, it falls back to IPv4. If not, it will timeout.

The solution is to disable IPv6 from the app as described here: How do I force my android app to use ipv4 instead of ipv6?

The problem is also documented here: https://github.com/square/okhttp/issues/506#issuecomment-765899011



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source