Android WearOS 应用 SocketTimeoutException 在蓝牙连接时无法连接到本地服务器

Android WearOS app SocketTimeoutException failing to connect to a local server when bluetooth connected

我正在开发一个连接到 API 并发出请求的智能手表应用程序。问题是,当我尝试连接到服务器并且我的 phone 没有连接到手表时,它运行良好并且连接到我的本地电脑,服务于 192.168 中的 rails API .1.132:3000。当手表通过蓝牙连接到 phone 时,问题就来了。我收到此错误:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.victorrubia.tfg, PID: 5079
    java.net.SocketTimeoutException: failed to connect to /192.168.1.132 (port 3000) from /192.168.167.239 (port 37933) after 10000ms
        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:63)
        at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.kt:295)
        at okhttp3.internal.connection.RealConnection.connect(RealConnection.kt:207)
        at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:226)
        at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:106)
        at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:74)
        at okhttp3.internal.connection.RealCall.initExchange$okhttp(RealCall.kt:255)
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:32)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
        at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
        at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201)
        at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:517)
        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)

我不明白当手表仅通过 WIFI 连接时,它怎么能很好地连接到我的服务器,而当它也与 phone 配对时,它无法连接到我的服务器。我使用的智能手表是通过ADB WIFI连接的TicWatch 3。

我尝试向 google.com 等远程域发出 GET 请求,并且在这两种情况下(仅连接到 WIFI 和 WIFI+蓝牙)都表现良好,所以如果有人能提供帮助,我将不胜感激我来解决这个问题。

PD:我也看过this question,但没有提供解决方案。

我不确定是否无法通过蓝牙专门连接到本地地址,但您可以请求特定网络并将其设置为默认网络。

https://github.com/square/okhttp/issues/2404

或使用 socketfactory 指定它

https://programmer.ink/think/the-implementation-of-okhttp-multi-network-communication.html

                public void onAvailable(final Network network) {
                    super.onAvailable(network);
                    //After the network is connected
                    SocketFactory socketFactory = network.getSocketFactory();
                    //If you use the eclipse MQTT package, you need to set the
                    mqttConnectOptions.setSocketFactory(socketFactory);
                    //If you use regular network connection, okhttp, you need to set
                    OkHttpClient okHttpClient = new OkHttpClient.Builder()
                            //.proxy(Proxy.NO_PROXY)
                            .socketFactory(socketFactory)
                            .dns(new Dns() {
                                @Override
                                public List<InetAddress> lookup(@NonNull String hostname) throws UnknownHostException {
                                    return Arrays.asList(network.getAllByName(hostname));
                                }
                            })
                            .build();