androidkotlinretrofitwear-osandroid-wear-data-api

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


I am developing a smartwatch app which connects to an API and make requests. The thing is, when I try to connect to the server and my phone is not connected to the watch, it works well and it connects to my local pc serving a rails API in 192.168.1.132:3000. The problem comes when the watch is connected to the phone via bluetooth. I get this error:

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)

I can't understand how is possible the watch is connecting well to my server when it is only connected via WIFI and when it is also paired with the phone it cannot connect to my server. The smartwatch I am using is a TicWatch 3 connected via ADB WIFI.

I have tried to make a GET request to a remote domain such as google.com and it performs well in both cases (connected only to WIFI and WIFI+Bluetooth) so I would really appreciate if anyone could help me sort this out.

PD: I have also looked at this question but no solution was provided.


Solution

  • I'm not sure about the failure to connect specifically to local addresses over bluetooth, but you can request a specific network and set it as the default.

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

    or specify it using a 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();