Search code examples
androidreact-nativesocket.ioexpo

socket.io on expo not connecting from android


Everything works fine on iOS but on Android it doesn't connect Here's my code

import { useState, useEffect } from 'react'
import { io } from 'socket.io-client'
const URL = 'http://localhost:8001'
const socket = io(URL)

const useSocket = () => {
  const [isConnected, setIsConnected] = useState(socket.connected)

  useEffect(() => {
    const onConnect = () => setIsConnected(true)
    const onDisconnect = () => setIsConnected(false)
    if (!socket.connected) {
      socket.connect()
    }
    socket.on('connect', onConnect)
    socket.on('disconnect', onDisconnect)

    return () => {
      socket.off('connect', onConnect)
      socket.off('disconnect', onDisconnect)
    }
  }, [])

  return { socket, isConnected }
}

export default useSocket

UPDATE:
It works if i replace
const URL = 'http://localhost:8001'
with
const URL = 'http://192.168.1.91:8001'
which is my local IP on the network

I'm going to leave the question open because it would be very useful to be able to just use localhost or 127.0.0.1 instead of a specific IP


Solution

  • Although it's a different type of request, the solution and reasoning behind it are the same as this question: React Native Android Fetch failing on connection to local API

    It's working on the iOS sim because, as a simulator, it shares its network config with the host machine. The Android emulator, on the other hand, is a discrete device with its own local IP, so localhost tells your app to search the Android's internal network.

    Your solution of using the full local IP address of the host machine is the easiest way around this.

    For development purposes, you could also use a shell script at build time to store the host machine's IP in an environment variable. Then you can use a tool like react-native-config to read the variable in your app. If you'd like more info on that, let me know.