0

Which would be the right way to make a TCP request using Socket in kotlin by using CoroutineScope?

by using GlobalScope.async the call works properly but i get the inspector errors on socket which says: Inappropriate blocking method call

The socket call should be done from a handler function and i was trying to do it by using Coroutine IO but when i try to run it i get the error:

FATAL EXCEPTION: DefaultDispatcher-worker-1

Here is my code:

private fun handlePhoneCall(
    response: CallResponse.Builder,
    phoneNumber: String
): CallResponse.Builder {
    val ipCassa = PreferenceManager.getDefaultSharedPreferences(this).getString("server", "127.0.0.1")

    GlobalScope.launch(IO) {
        Socket(ipCassa, 50000).use { socket: Socket ->
            val outputStream = socket.getOutputStream()
            outputStream.write(data.toByteArray())
            outputStream.flush()
        }.runCatching {

        }.onFailure {
            Log.e("SOCKET", it.message.toString())
        }
    }

    return response
}
NiceToMytyuk
  • 3,644
  • 3
  • 39
  • 100
  • 1
    This particular warning has lots of false positives since Kotlin 1.4. I think your code is fine, other than using GlobalScope. https://elizarov.medium.com/the-reason-to-avoid-globalscope-835337445abc – Tenfour04 Mar 29 '21 at 13:24

1 Answers1

1

Use withContext(Dispatchers.IO) {} can get rid of the Inappropriate blocking method call warning. Following is my example of using Socket with my receipt printer:

In ViewModel:

class FirstViewModel : ViewModel() {
    private val uiScope = viewModelScope

    fun print() {
        uiScope.launch {
            //show loading dialog

            PrintService.print()  //suspend function, won't run next line until it finishes

            //hide loading dialog
        }
    }
}

In Util Class:

object PrintService {
    suspend fun print() {
        withContext(Dispatchers.IO) {
            try {
                val socket = Socket("192.168.1.111", 9100)
                val outputStream = socket.getOutputStream()

                outputStream.use {
                    it.write("xxx".toByteArray())
                }
            } catch (e: IOException) {
                //log your error
            }
        }
    }
}

Demo: https://youtu.be/U0RkzWesgnc


Helpful reading:

Sam Chen
  • 7,597
  • 2
  • 40
  • 73