Skip to content

Android SignalR Java client StackOverFlow  #29477

@nts0311

Description

@nts0311

Describe the bug

I have an app that is a media client and is used in restaurants to present video, image, audio ... . It used SignalR to receive command to download media file, control audio, scheduled media play time,... . And it will ping to server every 15s to check the connection.
It is intended to run 24/7, all day long. But after about a day of running, the app crash because of StackOverflow exception in SignalR

To Reproduce

Code use for open connection and receiving command:

private fun connectToHub() {
        openNewConnectionJob = lifecycleScope.launch {
            val connectionId = openConnection()

            if (connectionId != null) {
                Log.d("Connected", connectionId)
                pingTimer()
            }

            openNewConnectionJob = null
        }
    }

    private suspend fun openConnection(): String? {
        //open connection on another thread
        return withContext(Dispatchers.Default)
        {
            try {
                hubConnection!!.start().blockingAwait()
                hubConnection!!.connectionId
            } catch (e: Exception) {
                Log.e(LOG_TAG, "error connecting tto hub")
                null
            }
        }
    }

    private fun onMessage() {
        hubConnection?.on(
            "ReceiveMessage",
            { command: String?, message: String? ->
                mainActivity.runOnUiThread {
                    Log.d("command", command ?: "")
                    Log.d("message", message ?: "")
                    
                    //Handle command from server in MainActivity
                    onMessageListener.invoke(command, message)

                    if (command != null && message != null && command == Status.PONG) {
                        lastPing = message
                        Log.d("last ping", lastPing)
                    }
                }
            },
            String::class.java,
            String::class.java
        )
    }

Code use for ping to server

//call after sucessfully init connection to hub
private fun pingTimer() {
        pingHubJob?.cancel()
        pingHubJob = lifecycleScope.launch {
            while (true) {
                pingHub()
                Log.d("pingtimer", "ping")
                delay(15000)


				//If loosed connection to hub, create a new connection
                val dateformat = SimpleDateFormat("dd/MM/yyyy HH:mm:ss")
                if (lastPing != "") {
                    try {

                        val now = Calendar.getInstance()
                        val lastPingTime = Calendar.getInstance().apply {
                            time = dateformat.parse(lastPing)
                        }

                        if (now.timeInMillis - lastPingTime.timeInMillis > 45000) {
                            Log.e(LOG_TAG, "Losed hub connection")

                            if (hubConnection != null)
                                hubConnection!!.stop()

                            createNewHubConnection()
                        }
                    } catch (e: Exception) {
                        Log.e(LOG_TAG, e.message)
                        e.printStackTrace()
                    }
                }
            }
        }
    }
	
	fun sendMessage(mess: String, command: String) {
        try {
            hubConnection!!.invoke(
                command,
                Utils.getDeviceId(mainActivity.applicationContext),
                mess
            )
        } catch (e: Exception) {
            Log.e(LOG_TAG, e.message)
            e.printStackTrace()
        }
    }
	
	fun pingHub() {
        try {
            if (!mainActivity.isFinishing && hubConnection != null) {

                
               // message = {"ConnectionId":"QEzbIsv4J43bh2nnkQmidw","IMEI":"18:93:7F:E8:EE:37","StartTime":"21/01/2021 10:24:57","Status":"START","Video":"{\"Index\":\"3\",\"Time\":\"0\"}"}
                sendMessage(message, Utils.ping)
            }
        } catch (e: java.lang.Exception) {
            e.printStackTrace()

        }
    }

Exceptions (if any)

Stacktrace :
log.txt

2021.01.19 at 22:33:08

Thread name: OkHttp Dispatcher
Message: stack size 1037KB
Cause: null
Stack trace: 
java.lang.StackOverflowError: stack size 1037KB
at io.reactivex.internal.operators.single.SingleFlatMapCompletable$FlatMapCompletableObserver.onError(SingleFlatMapCompletable.java:97)
	at io.reactivex.internal.operators.completable.CompletableConcatArray$ConcatInnerObserver.onError(CompletableConcatArray.java:60)
...
at io.reactivex.internal.operators.single.SingleFlatMapCompletable$FlatMapCompletableObserver.onError(SingleFlatMapCompletable.java:97)
	at io.reactivex.internal.operators.completable.CompletableConcatArray$ConcatInnerObserver.onError(CompletableConcatArray.java:60)
	at io.reactivex.internal.operators.single.SingleFlatMapCompletable$FlatMapCompletableObserver.onError(SingleFlatMapCompletable.java:97)
	at io.reactivex.subjects.SingleSubject.onError(SingleSubject.java:153)
	at com.microsoft.signalr.DefaultHttpClient$2.onFailure(DefaultHttpClient.java:149)
	at okhttp3.RealCall$AsyncCall.execute(RealCall.java:180)
	at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
	at java.lang.Thread.run(Thread.java:764)

Further technical details

SignalR Java Client 5.0.1 and 3.3.1 have this error

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-signalrIncludes: SignalR clients and serversbugThis issue describes a behavior which is not expected - a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions