Skip to content

Commit 50e5390

Browse files
alanleedevuffoltzl
authored and
uffoltzl
committed
Convert ReconnectingWebSocket.java to Kotlin (facebook#50614)
Summary: Pull Request resolved: facebook#50614 Convert Java to Kotlin Changelog: [Internal] Reviewed By: cortinico Differential Revision: D72750330 fbshipit-source-id: 03014c47938697a337109a6d213388837eccfb71
1 parent 440f0e0 commit 50e5390

File tree

3 files changed

+160
-200
lines changed

3 files changed

+160
-200
lines changed

packages/react-native/ReactAndroid/api/ReactAndroid.api

+4-4
Original file line numberDiff line numberDiff line change
@@ -3272,15 +3272,15 @@ public class com/facebook/react/packagerconnection/PackagerConnectionSettings {
32723272

32733273
public final class com/facebook/react/packagerconnection/ReconnectingWebSocket : okhttp3/WebSocketListener {
32743274
public fun <init> (Ljava/lang/String;Lcom/facebook/react/packagerconnection/ReconnectingWebSocket$MessageCallback;Lcom/facebook/react/packagerconnection/ReconnectingWebSocket$ConnectionCallback;)V
3275-
public fun closeQuietly ()V
3276-
public fun connect ()V
3275+
public final fun closeQuietly ()V
3276+
public final fun connect ()V
32773277
public fun onClosed (Lokhttp3/WebSocket;ILjava/lang/String;)V
32783278
public fun onFailure (Lokhttp3/WebSocket;Ljava/lang/Throwable;Lokhttp3/Response;)V
32793279
public fun onMessage (Lokhttp3/WebSocket;Ljava/lang/String;)V
32803280
public fun onMessage (Lokhttp3/WebSocket;Lokio/ByteString;)V
32813281
public fun onOpen (Lokhttp3/WebSocket;Lokhttp3/Response;)V
3282-
public fun sendMessage (Ljava/lang/String;)V
3283-
public fun sendMessage (Lokio/ByteString;)V
3282+
public final fun sendMessage (Ljava/lang/String;)V
3283+
public final fun sendMessage (Lokio/ByteString;)V
32843284
}
32853285

32863286
public abstract interface class com/facebook/react/packagerconnection/ReconnectingWebSocket$ConnectionCallback {

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/ReconnectingWebSocket.java

-196
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
package com.facebook.react.packagerconnection
9+
10+
import android.os.Handler
11+
import android.os.Looper
12+
import com.facebook.common.logging.FLog
13+
import java.io.IOException
14+
import java.nio.channels.ClosedChannelException
15+
import java.util.concurrent.TimeUnit
16+
import okhttp3.OkHttpClient
17+
import okhttp3.Request
18+
import okhttp3.Response
19+
import okhttp3.WebSocket
20+
import okhttp3.WebSocketListener
21+
import okio.ByteString
22+
23+
/** A wrapper around WebSocketClient that reconnects automatically */
24+
public class ReconnectingWebSocket(
25+
private val url: String,
26+
private var messageCallback: MessageCallback?,
27+
private val connectionCallback: ConnectionCallback?
28+
) : WebSocketListener() {
29+
30+
public interface MessageCallback {
31+
public fun onMessage(text: String)
32+
33+
public fun onMessage(bytes: ByteString)
34+
}
35+
36+
public interface ConnectionCallback {
37+
public fun onConnected()
38+
39+
public fun onDisconnected()
40+
}
41+
42+
private val handler = Handler(Looper.getMainLooper())
43+
private val okHttpClient: OkHttpClient =
44+
OkHttpClient.Builder()
45+
.connectTimeout(10, TimeUnit.SECONDS)
46+
.writeTimeout(10, TimeUnit.SECONDS)
47+
.readTimeout(0, TimeUnit.MINUTES) // Disable timeouts for read
48+
.build()
49+
private var closed = false
50+
private var suppressConnectionErrors = false
51+
private var webSocket: WebSocket? = null
52+
53+
public fun connect(): Unit {
54+
check(!closed) { "Can't connect closed client" }
55+
56+
val request = Request.Builder().url(url).build()
57+
okHttpClient.newWebSocket(request, this)
58+
}
59+
60+
@Synchronized
61+
private fun delayedReconnect() {
62+
// check that we haven't been closed in the meantime
63+
if (!closed) {
64+
connect()
65+
}
66+
}
67+
68+
private fun reconnect() {
69+
check(!closed) { "Can't reconnect closed client" }
70+
71+
if (!suppressConnectionErrors) {
72+
FLog.w(TAG, "Couldn't connect to \"$url\", will silently retry")
73+
suppressConnectionErrors = true
74+
}
75+
76+
handler.postDelayed({ delayedReconnect() }, RECONNECT_DELAY_MS)
77+
}
78+
79+
public fun closeQuietly(): Unit {
80+
closed = true
81+
closeWebSocketQuietly()
82+
messageCallback = null
83+
84+
connectionCallback?.onDisconnected()
85+
}
86+
87+
private fun closeWebSocketQuietly() {
88+
try {
89+
webSocket?.close(1_000, "End of session")
90+
} catch (e: Exception) {
91+
// swallow, no need to handle it here
92+
}
93+
webSocket = null
94+
}
95+
96+
private fun abort(message: String, cause: Throwable) {
97+
FLog.e(TAG, "Error occurred, shutting down websocket connection: $message", cause)
98+
closeWebSocketQuietly()
99+
}
100+
101+
@Synchronized
102+
override fun onOpen(webSocket: WebSocket, response: Response) {
103+
this.webSocket = webSocket
104+
suppressConnectionErrors = false
105+
106+
connectionCallback?.onConnected()
107+
}
108+
109+
@Synchronized
110+
override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
111+
if (this.webSocket != null) {
112+
abort("Websocket exception", t)
113+
}
114+
if (!closed) {
115+
connectionCallback?.onDisconnected()
116+
reconnect()
117+
}
118+
}
119+
120+
@Synchronized
121+
override fun onMessage(webSocket: WebSocket, text: String) {
122+
messageCallback?.onMessage(text)
123+
}
124+
125+
@Synchronized
126+
override fun onMessage(webSocket: WebSocket, bytes: ByteString) {
127+
messageCallback?.onMessage(bytes)
128+
}
129+
130+
@Synchronized
131+
override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
132+
this.webSocket = null
133+
if (!closed) {
134+
connectionCallback?.onDisconnected()
135+
reconnect()
136+
}
137+
}
138+
139+
@Synchronized
140+
@Throws(IOException::class)
141+
public fun sendMessage(message: String): Unit {
142+
webSocket?.send(message) ?: throw ClosedChannelException()
143+
}
144+
145+
@Synchronized
146+
@Throws(IOException::class)
147+
public fun sendMessage(message: ByteString): Unit {
148+
webSocket?.send(message) ?: throw ClosedChannelException()
149+
}
150+
151+
private companion object {
152+
private val TAG: String = ReconnectingWebSocket::class.java.simpleName
153+
154+
private const val RECONNECT_DELAY_MS = 2_000L
155+
}
156+
}

0 commit comments

Comments
 (0)