1

我正在使用带有 nodejs 服务器的 retrofit2 进行开发。当我在 android 中调用节点服务器时,会显示 android 的日志。请求立即结束。这个地址的结果是正确的。当我去这个地址时,json 结果显示正确。但在 android 中我无法与节点服务器通信 android 客户端。如您所见,尽管我将超时设置为 1 分钟,但我收到了错误消息。我不知道为什么我无法与服务器通信。有人知道吗?在 nodejs 中,它没有显示任何日志。

安卓日志

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)

显现

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

节点

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:当我使用模拟器将 url 更改为运行时http://10.0.2.2:5000/,结果是正确的。但是当我在手机上运行它时,它会显示上述错误。

应用模块

    @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 ScheduleNetwork {

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

    ): Call<CustomerItem>

}
4

1 回答 1

1

在评论中您提到您的 Android 不在本地 wifi 上,而是您使用的是运营商数据网络。你不能那样做™。如果您想连接到本地网络上的测试服务器,您的 Android 必须在同一网络的 Wifi 上。如果您想使用 Android 的运营商数据网络进行连接,您的服务器必须位于公共网络地址上。

在您的 Java 回溯中,这是重要的一行。

java.net.SocketTimeoutException:在 60000 毫秒后无法从 /192.0.0.x(端口 39078)连接到 /192.168.0.xx(端口 5000)

让我们阅读这一行以了解详细信息。

  1. 套接字超时异常。此 Java 代码在等待连接到服务器后放弃了。

  2. to /192.168.0.xxx (port 5000)此代码尝试连接到在 192.168.0.xxx 端口 5000 上的本地专用网络上的机器上运行的服务器。您可能打算将其用作您的 nodejs 服务器。我们知道这是一个专用网络,因为所有地址192.168.x.y都是专用网络地址。所有地址也是如此10.x.y.z。我的专用网络和您的专用网络可能具有完全相同的地址。因此,公共网络从不尝试处理发往这些专用网络的流量。它只是忽略它。

  3. from /192.0.0.xxx (port 39078)你的本地机器,你的机器人,试图发起连接。它的地址192.0.0.xxx在您运营商的网络上。您的运营商网络检测到您正在尝试连接到192.168.x.y专用网络地址。公共网络根本不允许这样做,因此您的运营商会忽略它。

  4. after 60 000ms一分钟后,Android 上的 Java 代码就放弃了。当网络忽略流量时会发生超时。

于 2020-03-06T12:10:34.523 回答