Android Emulator connecting to node server in WSL2

Viewed 2211

I'm having a bad time working with Android Studios, WSL2 and React Native.

Every day I get something to work, other stuff breaks. Yesterday, everything was working fine, now I can't connect to my server from my app.

I don't know where to ask this exactly but I'm feeling desperate. I've been trying to solve this for about EIGHT DAYS. I can't. I need help.

I'm not a fluent developer. In order to clarify as much as possible, I did this step-by-step list.

Much of it is based on this tutorial, the only thing that made WSL2 + Android Studios work together.

What am I doing, in order:

  • Starting Hyper in WSL (Ubuntu 20)
  • Navigating to my React Native project folder
  • Opening Windows Terminal as admin
  • Run in Terminal:
adb kill-server
adb -a nodaemon server start
  • Then, in Hyper:
unset ADB_SERVER_SOCKET
socat -d -d TCP-LISTEN:5037,reuseaddr,fork TCP:$(cat /etc/resolv.conf | tail -n1 | cut -d " " -f 2):5037
  • I let both Terminal and Hyper running and don't close their windows/tabs.
  • In another Terminal window, I run:
iex "netsh interface portproxy delete v4tov4 listenport=8081 listenaddress=127.0.0.1" | out-null;
$WSL_CLIENT = bash.exe -c "ip addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'";
$WSL_CLIENT -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';
$WSL_CLIENT = $matches[0];
iex "netsh interface portproxy add v4tov4 listenport=8081 listenaddress=127.0.0.1 connectport=8081 connectaddress=$WSL_CLIENT"
  • Still in Terminal, I get my WSL ip using ipconfig. Let's say it's 172.22.32.1.
  • I open VS Code and change my Axios API connection to this IP. Eg:
import axios from 'axios';

const api = axios.create({
  baseURL: 'http://172.22.32.1:3333',
});

export default api;
  • I open a Android Studios AVD, named emulator-5554.
  • I run yarn start on Hyper. It shows "Welcome to React Native" etc.
  • In another tab, I run yarn android --variant=debug --deviceId emulator-5554 and wait it's completion.
  • At this point the app is running on my device. If I make changes on VS Code, it changes. Everything apparently running smoothly.
  • I start docker desktop (windows with WSL2 integration) and do docker ps to check if anything is started. Nothing is.
  • I run docker start mongo redis gostack-postgres (there's a reason to be using all this but I believe it's unrelated).
  • Then, docker ps:
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS
  NAMES
1a19b8e8914a        mongo               "docker-entrypoint.s…"   4 days ago          Up 5 seconds        0.0.0.0:27017->27017/tcp
  mongo
172505459df6        postgres            "docker-entrypoint.s…"   4 days ago          Up 4 seconds        0.0.0.0:5432->5432/tcp
  gostack-postgres
acac9fa31419        redis:alpine        "docker-entrypoint.s…"   5 days ago          Up 5 seconds        0.0.0.0:6379->6379/tcp
  redis
  • I navigate to the server folder and start it running yarn dev:server.
  • I test it using my front-end website on chrome, running on localhost:3000. The server works fine, as I can login and change information.
  • Again, I test the server using localhost:3333 in browser and receiving a connected message. Everything ok, so I kill the front-end website.
  • I try to login through my app, as I did in the website. It waits a few seconds... and gives me the [Error: Network Error] log in React Native Metro.
  • Ok, something is wrong with the connection. Let's try localhost instead of the IP. I change it in my API settings.
const api = axios.create({
  baseURL: 'http://localhost:3333',
});
  • In order to make sure everything is ok, I re-run yarn android --variant=debug --deviceId emulator-5554
  • This time, as soon as I press the login button, the app returns [Error: Network Error] (the other time it took a few to return me).
  • I believe this is not the IP I should be using. I try, then 0.0.0.0 and re-run yarn android.... After finished, I reload Metro with r.
  • [Error: Network Error]
1 Answers

You just need to run this script on windows powershell (as admin):

# DELETE ANY PREVIOUS FORWARD CONFIGURATION PORT
iex "netsh interface portproxy delete v4tov4 listenport=3333 listenaddress=127.0.0.1" | out-null;

# GET THE WSL IP AND CHECKS IT FORMAT xxx.xxx.xxx.xxx
$WSL_CLIENT = bash.exe -c "ip addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'";
$WSL_CLIENT -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';
$WSL_CLIENT = $matches[0];

# ADD PORTS FORWARD FROM WSL TO WINDOWS
#(With this command, windows port 3333 starts to listen port 3333 of wsl2)
iex "netsh interface portproxy add v4tov4 listenport=3333 listenaddress=127.0.0.1 connectport=3333 connectaddress=$WSL_CLIENT"

# TO CHECK ALL PORTS CONFIGURED:
netsh interface portproxy show all

If the code above doesn't works for you, you can also check this command:

# Its the same concept, works like a proxy forwarding Linux traffic

$ sysctl -w net.ipv4.conf.all.route_localnet=1
$ iptables -t nat -I PREROUTING -p tcp -j DNAT --to-destination 127.0.0.1 

I hope it works for you.

UPDATED

I've created a powershell script, so every time i restart my O.S. and my ip changes i just run it.

param ($ports=(8081, 3333, 3000), $listenaddress='0.0.0.0', $connectaddress, [switch]$show, [switch]$reset, [switch]$help)

# #[Ports]
# #All the ports you want to forward separated by coma
# $ports=@(8081, 3333);

if( $help ){
    write-host "Parameters:"
    write-host "show => show all portproxys configured."
    write-host "reset => reset all portproxys configured."
    write-host "ports (-ports 8081,3333)"
    write-host "listenaddress (-listenaddress 127.0.0.1)"
    write-host "connectaddress (-connectaddress 127.0.0.1)"
    exit;
}

if( $show ){
    netsh interface portproxy show all
    exit;
}

if( $reset ){
    netsh interface portproxy reset
    exit;
}

$remoteport = bash.exe -c "ip addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'"
$found = $remoteport -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';

if( $found ){
  $remoteport = $matches[0];
} else{
  write-host "The Script Exited, the ip address of WSL 2 cannot be found";
  exit;
}

if( $connectaddress ){
    $remoteport  = $connectaddress
}

for( $i = 0; $i -lt $ports.length; $i++ ){
  $port = $ports[$i];
  iex "netsh interface portproxy delete v4tov4 listenport=$port listenaddress=$listenaddress";
  iex "netsh interface portproxy add v4tov4 listenport=$port listenaddress=$listenaddress connectport=$port connectaddress=$remoteport";
  write-host "Port $port configured: `nListen address: $listenaddress`nConnect address: $remoteport"
}

# write-host "====================================================="
netsh interface portproxy show all

How to use: I saved this script as wslbridge.ps1 and put it in "C:\Windows\System32". To execute it just open powershell and type wslbridge (it will configure with defaults ports 8081, 3333, 3000 - *you can change this).

To list configured ports: wslbridge -show

To add new port configuration: wslbridge -port XXXX

To reset pre configured ports: wslbridge -reset

Cheers,

Related