TooTallNate / Java-WebSocket

A barebones WebSocket client and server implementation written in 100% Java.
http://tootallnate.github.io/Java-WebSocket
MIT License
10.53k stars 2.58k forks source link

when i call api reconnect the crash happen,please help me to check this issue #1343

Closed feidiwangdong closed 10 months ago

feidiwangdong commented 1 year ago

the error message is : Attempt to invoke virtual method 'long java.lang.Thread.getId()' on a null object reference

1 org.java_websocket.client.WebSocketClient.connect(WebSocketClient.java:375) 2 org.java_websocket.client.WebSocketClient.reconnect(WebSocketClient.java:315)

PhilipRoman commented 1 year ago

You need to show us the code that causes this. How else are we supposed to reproduce the issue?

feidiwangdong commented 1 year ago

class BtokWebSocketClient(var tgid: Long, var token: String?, serverURI: URI) : WebSocketClient(serverURI) { private val contentGenerator by lazy { SocketMessageSendCenter() } private var pingDelay = 6000L

private var retryTimes = 0

private var defaultRetryTime = 3000L // 默认三秒后进行重连

private var hasCacheTgLoginSuccessMsg = false

private var reTryDisposable: Disposable? = null
val deviceId: String by lazy {
    AppUtil.getDeviceId(HAndroid.getApplication())
}

@Volatile
private var socketQueue = DispatchQueue("socketQueue")

var isNeedConnect = true

private val reConnectRunnable = Runnable {
    HLog.e("==reConnectRunnable==")
    reConnect()
}

override fun onOpen(handshakedata: ServerHandshake) {
    retryTimes = 0
    HAndroid.cancelDisposable(reTryDisposable)
    socketQueue.cleanupQueue()
    HLog.e("BtokWebSocketClient onOpen")
}

override fun onClose(code: Int, reason: String, remote: Boolean) {
    HLog.e("BtokWebSocketClient ==closed with exit code $code additional info: $reason")
    sendReconnectPostManual(false)
}

override fun onWebsocketPing(conn: WebSocket, f: Framedata) {
    conn.sendFrame(PongFrame(f as PingFrame))
    Log.e("BtokWebSocketClient ==onWebsocketPing==", "")
    reConnectInterval(pingDelay / 1000 * 2, 5L) // 周期性任务,每隔5秒就会取重试链接
}

override fun onMessage(message: String) {
    HLog.e("BtokWebSocketClient ==received message: $message")
}

override fun onMessage(message: ByteBuffer) {

}

override fun onError(ex: Exception) {
    HLog.e("BtokWebSocketClient ==an error occurred:$ex")
}

private fun reConnect() {
    HLog.e("BtokWebSocketClient reConnect isClosed $isClosed isClosing $isClosing")
    if (isNeedConnect && this.isClosed && !this.isClosing) {
        try {
            this.reconnect()
        } catch (e: Throwable) {
            e.printStackTrace()
        }
    }
}

/**
 * 手动切换了账户后进行socket链接
 * @param reConnectByManual 是否是主动关闭的socket
 */
fun sendReconnectPostManual(reConnectByManual: Boolean) {
    HLog.e("BtokWebSocketClient ==sendReconnectPostManual reConnectByManual is :$reConnectByManual")
    if (reConnectByManual) {
        defaultRetryTime = 0
        retryTimes = 0
    } else {
        defaultRetryTime = 3000L
    }
    socketQueue.cleanupQueue()
    try {
        sendReConnectPost() // 已经提单到websocket进行咨询,如何解决刚创建的线程,下一行代码就出现空指针问题
    } catch (e: Throwable) {
        HLog.e("BtokWebSocketClient reconnect but error happen msg is :${e.message}")
    }
}

private fun sendReConnectPost() {
    if (isNeedConnect) {
        socketQueue.postRunnable(
            reConnectRunnable, if (retryTimes > 2) {
                Random.nextInt(30) * 1000L
            } else {
                defaultRetryTime
            }
        )
        retryTimes++
    }
}

override fun onSetSSLParameters(sslParameters: SSLParameters?) {
    if (Build.VERSION.SDK_INT >= 24) {
        super.onSetSSLParameters(sslParameters)
    }
}

/**
 * 周期性执行重联任务
 */
private fun reConnectInterval(delay: Long, interval: Long) {
    try {
        HAndroid.cancelDisposable(reTryDisposable)
        HLog.i(
            "BtokWebSocketClient start reConnectInterval delay is $delay interval is $interval"
        )
        reTryDisposable = Observable.interval(delay, interval, TimeUnit.SECONDS)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.io())
            .subscribe {
                HLog.i(
                    "BtokWebSocketClient reConnectInterval check"
                )
                sendReconnectPostManual(true)
            }
    } catch (e: Throwable) {
        e.printStackTrace()
    }
}

}

feidiwangdong commented 1 year ago

ps: socketQueue is instance of work thread

PhilipRoman commented 10 months ago

I'm 99% sure this is part of the issues fixed in #1367, should no longer happen using library version 1.5.5.