mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Convert ReconnectingWebSocket.java to Kotlin (#50614)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/50614 Convert Java to Kotlin Changelog: [Internal] Reviewed By: cortinico Differential Revision: D72750330 fbshipit-source-id: 03014c47938697a337109a6d213388837eccfb71
This commit is contained in:
committed by
Facebook GitHub Bot
parent
61c539fa6a
commit
f62bd98a32
@@ -3272,15 +3272,15 @@ public class com/facebook/react/packagerconnection/PackagerConnectionSettings {
|
||||
|
||||
public final class com/facebook/react/packagerconnection/ReconnectingWebSocket : okhttp3/WebSocketListener {
|
||||
public fun <init> (Ljava/lang/String;Lcom/facebook/react/packagerconnection/ReconnectingWebSocket$MessageCallback;Lcom/facebook/react/packagerconnection/ReconnectingWebSocket$ConnectionCallback;)V
|
||||
public fun closeQuietly ()V
|
||||
public fun connect ()V
|
||||
public final fun closeQuietly ()V
|
||||
public final fun connect ()V
|
||||
public fun onClosed (Lokhttp3/WebSocket;ILjava/lang/String;)V
|
||||
public fun onFailure (Lokhttp3/WebSocket;Ljava/lang/Throwable;Lokhttp3/Response;)V
|
||||
public fun onMessage (Lokhttp3/WebSocket;Ljava/lang/String;)V
|
||||
public fun onMessage (Lokhttp3/WebSocket;Lokio/ByteString;)V
|
||||
public fun onOpen (Lokhttp3/WebSocket;Lokhttp3/Response;)V
|
||||
public fun sendMessage (Ljava/lang/String;)V
|
||||
public fun sendMessage (Lokio/ByteString;)V
|
||||
public final fun sendMessage (Ljava/lang/String;)V
|
||||
public final fun sendMessage (Lokio/ByteString;)V
|
||||
}
|
||||
|
||||
public abstract interface class com/facebook/react/packagerconnection/ReconnectingWebSocket$ConnectionCallback {
|
||||
|
||||
-196
@@ -1,196 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.packagerconnection;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.facebook.common.logging.FLog;
|
||||
import com.facebook.infer.annotation.Nullsafe;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.WebSocket;
|
||||
import okhttp3.WebSocketListener;
|
||||
import okio.ByteString;
|
||||
|
||||
/** A wrapper around WebSocketClient that reconnects automatically */
|
||||
@Nullsafe(Nullsafe.Mode.LOCAL)
|
||||
public final class ReconnectingWebSocket extends WebSocketListener {
|
||||
private static final String TAG = ReconnectingWebSocket.class.getSimpleName();
|
||||
|
||||
private static final int RECONNECT_DELAY_MS = 2000;
|
||||
|
||||
public interface MessageCallback {
|
||||
void onMessage(String text);
|
||||
|
||||
void onMessage(ByteString bytes);
|
||||
}
|
||||
|
||||
public interface ConnectionCallback {
|
||||
void onConnected();
|
||||
|
||||
void onDisconnected();
|
||||
}
|
||||
|
||||
private final String mUrl;
|
||||
private final Handler mHandler;
|
||||
private final OkHttpClient mOkHttpClient;
|
||||
private boolean mClosed = false;
|
||||
private boolean mSuppressConnectionErrors;
|
||||
private @Nullable WebSocket mWebSocket;
|
||||
private @Nullable MessageCallback mMessageCallback;
|
||||
private @Nullable ConnectionCallback mConnectionCallback;
|
||||
|
||||
public ReconnectingWebSocket(
|
||||
String url,
|
||||
@Nullable MessageCallback messageCallback,
|
||||
@Nullable ConnectionCallback connectionCallback) {
|
||||
super();
|
||||
mUrl = url;
|
||||
mMessageCallback = messageCallback;
|
||||
mConnectionCallback = connectionCallback;
|
||||
mHandler = new Handler(Looper.getMainLooper());
|
||||
mOkHttpClient =
|
||||
new OkHttpClient.Builder()
|
||||
.connectTimeout(10, TimeUnit.SECONDS)
|
||||
.writeTimeout(10, TimeUnit.SECONDS)
|
||||
.readTimeout(0, TimeUnit.MINUTES) // Disable timeouts for read
|
||||
.build();
|
||||
}
|
||||
|
||||
public void connect() {
|
||||
if (mClosed) {
|
||||
throw new IllegalStateException("Can't connect closed client");
|
||||
}
|
||||
|
||||
Request request = new Request.Builder().url(mUrl).build();
|
||||
mOkHttpClient.newWebSocket(request, this);
|
||||
}
|
||||
|
||||
private synchronized void delayedReconnect() {
|
||||
// check that we haven't been closed in the meantime
|
||||
if (!mClosed) {
|
||||
connect();
|
||||
}
|
||||
}
|
||||
|
||||
private void reconnect() {
|
||||
if (mClosed) {
|
||||
throw new IllegalStateException("Can't reconnect closed client");
|
||||
}
|
||||
|
||||
if (!mSuppressConnectionErrors) {
|
||||
FLog.w(TAG, "Couldn't connect to \"" + mUrl + "\", will silently retry");
|
||||
mSuppressConnectionErrors = true;
|
||||
}
|
||||
|
||||
mHandler.postDelayed(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
delayedReconnect();
|
||||
}
|
||||
},
|
||||
RECONNECT_DELAY_MS);
|
||||
}
|
||||
|
||||
public void closeQuietly() {
|
||||
mClosed = true;
|
||||
closeWebSocketQuietly();
|
||||
mMessageCallback = null;
|
||||
|
||||
if (mConnectionCallback != null) {
|
||||
mConnectionCallback.onDisconnected();
|
||||
}
|
||||
}
|
||||
|
||||
private void closeWebSocketQuietly() {
|
||||
if (mWebSocket != null) {
|
||||
try {
|
||||
mWebSocket.close(1000, "End of session");
|
||||
} catch (Exception e) {
|
||||
// swallow, no need to handle it here
|
||||
}
|
||||
mWebSocket = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void abort(String message, Throwable cause) {
|
||||
FLog.e(TAG, "Error occurred, shutting down websocket connection: " + message, cause);
|
||||
closeWebSocketQuietly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onOpen(WebSocket webSocket, Response response) {
|
||||
mWebSocket = webSocket;
|
||||
mSuppressConnectionErrors = false;
|
||||
|
||||
if (mConnectionCallback != null) {
|
||||
mConnectionCallback.onConnected();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onFailure(
|
||||
@Nullable WebSocket webSocket, Throwable t, @Nullable Response response) {
|
||||
if (mWebSocket != null) {
|
||||
abort("Websocket exception", t);
|
||||
}
|
||||
if (!mClosed) {
|
||||
if (mConnectionCallback != null) {
|
||||
mConnectionCallback.onDisconnected();
|
||||
}
|
||||
reconnect();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onMessage(WebSocket webSocket, String text) {
|
||||
if (mMessageCallback != null) {
|
||||
mMessageCallback.onMessage(text);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onMessage(WebSocket webSocket, ByteString bytes) {
|
||||
if (mMessageCallback != null) {
|
||||
mMessageCallback.onMessage(bytes);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onClosed(WebSocket webSocket, int code, String reason) {
|
||||
mWebSocket = null;
|
||||
if (!mClosed) {
|
||||
if (mConnectionCallback != null) {
|
||||
mConnectionCallback.onDisconnected();
|
||||
}
|
||||
reconnect();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void sendMessage(String message) throws IOException {
|
||||
if (mWebSocket != null) {
|
||||
mWebSocket.send(message);
|
||||
} else {
|
||||
throw new ClosedChannelException();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void sendMessage(ByteString message) throws IOException {
|
||||
if (mWebSocket != null) {
|
||||
mWebSocket.send(message);
|
||||
} else {
|
||||
throw new ClosedChannelException();
|
||||
}
|
||||
}
|
||||
}
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.packagerconnection
|
||||
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import com.facebook.common.logging.FLog
|
||||
import java.io.IOException
|
||||
import java.nio.channels.ClosedChannelException
|
||||
import java.util.concurrent.TimeUnit
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import okhttp3.WebSocket
|
||||
import okhttp3.WebSocketListener
|
||||
import okio.ByteString
|
||||
|
||||
/** A wrapper around WebSocketClient that reconnects automatically */
|
||||
public class ReconnectingWebSocket(
|
||||
private val url: String,
|
||||
private var messageCallback: MessageCallback?,
|
||||
private val connectionCallback: ConnectionCallback?
|
||||
) : WebSocketListener() {
|
||||
|
||||
public interface MessageCallback {
|
||||
public fun onMessage(text: String)
|
||||
|
||||
public fun onMessage(bytes: ByteString)
|
||||
}
|
||||
|
||||
public interface ConnectionCallback {
|
||||
public fun onConnected()
|
||||
|
||||
public fun onDisconnected()
|
||||
}
|
||||
|
||||
private val handler = Handler(Looper.getMainLooper())
|
||||
private val okHttpClient: OkHttpClient =
|
||||
OkHttpClient.Builder()
|
||||
.connectTimeout(10, TimeUnit.SECONDS)
|
||||
.writeTimeout(10, TimeUnit.SECONDS)
|
||||
.readTimeout(0, TimeUnit.MINUTES) // Disable timeouts for read
|
||||
.build()
|
||||
private var closed = false
|
||||
private var suppressConnectionErrors = false
|
||||
private var webSocket: WebSocket? = null
|
||||
|
||||
public fun connect(): Unit {
|
||||
check(!closed) { "Can't connect closed client" }
|
||||
|
||||
val request = Request.Builder().url(url).build()
|
||||
okHttpClient.newWebSocket(request, this)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun delayedReconnect() {
|
||||
// check that we haven't been closed in the meantime
|
||||
if (!closed) {
|
||||
connect()
|
||||
}
|
||||
}
|
||||
|
||||
private fun reconnect() {
|
||||
check(!closed) { "Can't reconnect closed client" }
|
||||
|
||||
if (!suppressConnectionErrors) {
|
||||
FLog.w(TAG, "Couldn't connect to \"$url\", will silently retry")
|
||||
suppressConnectionErrors = true
|
||||
}
|
||||
|
||||
handler.postDelayed({ delayedReconnect() }, RECONNECT_DELAY_MS)
|
||||
}
|
||||
|
||||
public fun closeQuietly(): Unit {
|
||||
closed = true
|
||||
closeWebSocketQuietly()
|
||||
messageCallback = null
|
||||
|
||||
connectionCallback?.onDisconnected()
|
||||
}
|
||||
|
||||
private fun closeWebSocketQuietly() {
|
||||
try {
|
||||
webSocket?.close(1_000, "End of session")
|
||||
} catch (e: Exception) {
|
||||
// swallow, no need to handle it here
|
||||
}
|
||||
webSocket = null
|
||||
}
|
||||
|
||||
private fun abort(message: String, cause: Throwable) {
|
||||
FLog.e(TAG, "Error occurred, shutting down websocket connection: $message", cause)
|
||||
closeWebSocketQuietly()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onOpen(webSocket: WebSocket, response: Response) {
|
||||
this.webSocket = webSocket
|
||||
suppressConnectionErrors = false
|
||||
|
||||
connectionCallback?.onConnected()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
|
||||
if (this.webSocket != null) {
|
||||
abort("Websocket exception", t)
|
||||
}
|
||||
if (!closed) {
|
||||
connectionCallback?.onDisconnected()
|
||||
reconnect()
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onMessage(webSocket: WebSocket, text: String) {
|
||||
messageCallback?.onMessage(text)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onMessage(webSocket: WebSocket, bytes: ByteString) {
|
||||
messageCallback?.onMessage(bytes)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
|
||||
this.webSocket = null
|
||||
if (!closed) {
|
||||
connectionCallback?.onDisconnected()
|
||||
reconnect()
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
@Throws(IOException::class)
|
||||
public fun sendMessage(message: String): Unit {
|
||||
webSocket?.send(message) ?: throw ClosedChannelException()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
@Throws(IOException::class)
|
||||
public fun sendMessage(message: ByteString): Unit {
|
||||
webSocket?.send(message) ?: throw ClosedChannelException()
|
||||
}
|
||||
|
||||
private companion object {
|
||||
private val TAG: String = ReconnectingWebSocket::class.java.simpleName
|
||||
|
||||
private const val RECONNECT_DELAY_MS = 2_000L
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user