Я разрабатываю приложение для умных часов, которое подключается к 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: Я также просмотрел этот вопрос, но решения не нашел.
Да, на самом деле это похоже на то, что телефон проксирует запросы износа с локальными IP-адресами. Я искал его и не мог найти много информации. Кажется, что когда износ подключен к телефону через Bluetooth, он ожидает подключения к удаленным серверам, а не к локальным. Единственный обходной путь, который я нашел, — принудительно подключиться через WiFi, когда доступен как упоминалось здесь (на данный момент это всегда так, поскольку я разрабатываю и тестирую приложение дома)
Я не уверен в невозможности подключения конкретно к локальным адресам по 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();
Может ли ваш телефон подключиться к той же сети?