Приложение Android WearOS SocketTimeoutException не может подключиться к локальному серверу при подключении Bluetooth

Я разрабатываю приложение для умных часов, которое подключается к API и отправляет запросы. Дело в том, что когда я пытаюсь подключиться к серверу, а мой телефон не подключен к часам, они работают хорошо и подключаются к моему локальному компьютеру, обслуживающему API-интерфейс 192.168.1.132:3000. Проблема возникает, когда часы подключены к телефону через Bluetooth. Я получаю эту ошибку:

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, а когда они также сопряжены с телефоном, они не могут подключиться к моему серверу. Я использую умные часы TicWatch 3, подключенные через ADB WIFI.

Я попытался сделать запрос GET к удаленному домену, такому как google.com, и он хорошо работает в обоих случаях (подключение только к WIFI и WIFI + Bluetooth), поэтому я был бы очень признателен, если бы кто-нибудь помог мне разобраться.

PD: Я также просмотрел этот вопрос, но решения не нашел.

Может ли ваш телефон подключиться к той же сети?

Yuri Schimke 16.03.2022 19:40

Да, на самом деле это похоже на то, что телефон проксирует запросы износа с локальными IP-адресами. Я искал его и не мог найти много информации. Кажется, что когда износ подключен к телефону через Bluetooth, он ожидает подключения к удаленным серверам, а не к локальным. Единственный обходной путь, который я нашел, — принудительно подключиться через WiFi, когда доступен как упоминалось здесь (на данный момент это всегда так, поскольку я разрабатываю и тестирую приложение дома)

Victor Rubia 16.03.2022 23:02
1
2
29
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я не уверен в невозможности подключения конкретно к локальным адресам по bluetooth, но вы можете запросить конкретную сеть и установить ее по умолчанию.

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();

Другие вопросы по теме