birdofpreyru/react-native-static-server

Fail to open Server with WiFi without Internet and cellular enabled (android)

Opened this issue · 3 comments

Somewhat related to #21

How to reproduce:

  • be on Android
  • connect to a local wifi without Internet
  • have cellular turned on
  • open a server with nonLocal:true (other devices in the wifi should be able to reach it), do not specify hostname + port (for reasons I am currently not able to retrieve my ip within the network)
    => Server crashes

I´m currently investigating if I can get a hold of the ip + port to use in that network but wanted to get in touch with you anyway.

If I turn off cellular, still use the wifi ( without internet connection ) and do not specify port + host static server will retrieve the correct ip + port, open the server and other devices within the network can access the server.

Would you be able to handle the case cellular + no internet WiFi on your side ?

Greetings

Hi @RobinSchuler , yes, it is the same stuff as #21.

The problem is clear — if you set nonLocal flag, the library on Android relies on this simple function to auto-select IP address to bind to:

@ReactMethod
override fun getLocalIpAddress(promise: Promise) {
try {
val en = NetworkInterface.getNetworkInterfaces()
while (en.hasMoreElements()) {
val intf = en.nextElement()
val enumIpAddr = intf.inetAddresses
while (enumIpAddr.hasMoreElements()) {
val inetAddress = enumIpAddr.nextElement()
if (!inetAddress.isLoopbackAddress) {
val ip = inetAddress.hostAddress
if (isIPv4Address(ip)) {
promise.resolve(ip)
return
}
}
}
}
promise.resolve("127.0.0.1")
} catch (e: Exception) {
Errors.FAIL_GET_LOCAL_IP_ADDRESS().reject(promise)
}
}

you see, it just cycles through all network interfaces, until the first one which is associated with a valid IPv4 address, and tries to use that address for the server. Apparently it does not result in the correct local IP in the situation you describe.

On my end, I don't know exactly how to correctly select the network interface among available ones; and I still have no motivation to spend my time on figuring it out and implementing it correctly. So, if you want to spend you time on making it work better — PRs are welcome!

Yeah, on the high level my thoughts regarding it were that there might be different needs to select the exact interface (like select local WIFI address, or select the mobile, or whatever makes sense). So I thought to deprecate nonLocal flag altogether, and instead allow to assign into hostname (apart of valid IP addresses) some special string constants which would be passed into that IP selection function and tell what exactly should be selected.

Thanks for the fast reply @birdofpreyru,

My first thought was also something like a "preferred Network" prop (or alternative a exclude network), where the code snippet you posted would be altered to look for a match with the given name.
If "preferred Network" is not given or the name not found it would return the first match (like currently)

@birdofpreyru
FYI, I patched it on my side (patch-package) with a filter prop. The filter checks if the interface name (NetworkInterface class) contains the filter criteria.
(Interfaces my mobile device had were "wlan0", sth for roaming (cant remember the exact name) and something else (dummy I think)