1

I'm dev-ing using retrofit2 with nodejs server. when I call to node server in android, the log of android show. the request is ended instantly. the result of this address is right. when I go to this address, json result show right. but in android I cant communicate android client with node server. as u can see, I get the error message although I set the timeout 1 minute. I don't know why I can't communicate with server. is there any one know this? in nodejs, it didn't show any log.

android log

D/OkHttp: --> GET http://192.168.0.xx:5000/api/customers
    --> END GET

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.haii.schedulemanager, PID: 8169
    java.net.SocketTimeoutException: failed to connect to /192.168.0.xx (port 5000) from /192.0.0.x (port 39078) after 60000ms
        at libcore.io.IoBridge.connectErrno(IoBridge.java:185)
        at libcore.io.IoBridge.connect(IoBridge.java:129)
        at java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:137)
        at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:390)
        at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:230)
        at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:212)
        at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:436)
        at java.net.Socket.connect(Socket.java:621)
        at okhttp3.internal.platform.AndroidPlatform.connectSocket(AndroidPlatform.kt:57)
        at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.kt:266)
        at okhttp3.internal.connection.RealConnection.connect(RealConnection.kt:180)
        at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:238)
        at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:111)
        at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:79)
        at okhttp3.internal.connection.Transmitter.newExchange$okhttp(Transmitter.kt:163)
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:35)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:82)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
        at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:84)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:71)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
        at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.kt:219)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
        at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.kt:194)
        at okhttp3.RealCall$AsyncCall.run(RealCall.kt:138)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:764)

manifest

        android:usesCleartextTraffic="true" //this is for http

nodejs

app.get('/api/customers',(req,res)=>{

    let today = moment(new Date()).format("YYYY-MM-DD");
    let date="";

    if(moment().day()===0){
        date = getWeekday(moment(new Date()).add('days',7).format("YYYY-MM-DD"),"Saturday");
    }else{
        date = getWeekday(today,"Saturday");
    }


    let sql = "select * from customer "+
            "where isDeleted=0 and createdDate between '"+today+"' and '"+ date+"'"; 
    const params = ""
    console.log(sql);

    connection.query(
        sql,params,
        (err,rows,fields)=>{
            console.log(rows);
            res.send(rows);
        }
    )
});

ps: when I run with emulator changing url to http://10.0.2.2:5000/, the result come right. but when I run this at my phone, it show above error.

applicationModule

    @JvmStatic
    @Singleton
    @Provides
    fun provideTaskNetwork() : ScheduleNetwork {
        return Retrofit.Builder()
            .baseUrl("http://192.168.0.xx:5000/")
            .addConverterFactory(GsonConverterFactory.create())
            .client(provideOkhttp())
            .build()
            .create(ScheduleNetwork::class.java)

interface


interface ScheduleNetwork {

    @GET("api/customers")
    fun getCustomers(

    ): Call<CustomerItem>

}
O. Jones
  • 103,626
  • 17
  • 118
  • 172
jakchang
  • 402
  • 5
  • 13
  • Your mobile and server both are on same network right? please also show your `ip`, also it will not show any log in node as `phone` is not communication with the server, please also show your `base_url` and GET request `interface` – Rahul Gaur Mar 06 '20 at 11:41
  • my mobile ip is 192.0.0.5 (data network not wifi) and my desktop is 192.168.0.35. it's different network. – jakchang Mar 06 '20 at 11:42
  • you can not use `localhost` on different networks, your device and desktop should be on same network – Rahul Gaur Mar 06 '20 at 11:43
  • so I changed localohst to 192.168.0.xx . localhost to real network address. – jakchang Mar 06 '20 at 11:47
  • 192.162.x.x are [private IPs](https://whatismyipaddress.com/private-ip) – Rahul Gaur Mar 06 '20 at 11:49
  • when I use wifi it's working well but when I use external network, I got above error. why this occur? I don't understand. And what should I do for using server from external network? – jakchang Mar 06 '20 at 11:50
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/209156/discussion-between-rahul-gaur-and-jakchang). – Rahul Gaur Mar 06 '20 at 11:50

1 Answers1

1

In a comment you mentioned that your Android is not on your local wifi, but rather you're using the carrier data network. You Can't Do That™. If you want to connect to a test server on your local network, your Android must be on the Wifi for that same network. If you want to connect using your Android's carrier data network, your server must be on a public network address.

In your Java traceback, this is the important line.

java.net.SocketTimeoutException: failed to connect to /192.168.0.xx (port 5000) from /192.0.0.x (port 39078) after 60000ms

Let's read this line for details.

  1. SocketTimeoutException. This Java code gave up after waiting for a connection to a server.

  2. to /192.168.0.xxx (port 5000) This code tried to connect to a server running on a machine on a local private network on 192.168.0.xxx at port 5000. You probably intend that to be your nodejs server. We know it's a private network because all addresses 192.168.x.y are private-network addresses. So are all addresses 10.x.y.z. My private network and yours might have the exact same addresses. So the public network never tries to handle traffic addressed to those private networks. It just ignores it.

  3. from /192.0.0.xxx (port 39078) Your local machine, your android, attempted to originate the connection. Its address is 192.0.0.xxx on your carrier's network. Your carrier's network detects that you're trying to connect to a 192.168.x.y private-network address. That's simply not allowed from the public network, so your carrier ignores it.

  4. after 60 000ms The Java code on your Android gave up after a minute. Timeouts happen when networks ignore traffic.

O. Jones
  • 103,626
  • 17
  • 118
  • 172