Followers

Grpc Stream Kotlin Example | Grpc Streaming Android Code

Grpc Stream Kotlin Example 

Integrate the below steps for the Grpc stream to work in Android


Step 1: 

Create a folder proto in main folder and place your proto files in it.


Step 2: 

Add the below lines to your build.gradle file

apply plugin: 'com.google.protobuf'

android {
    ------
}
protobuf {
    protoc { artifact = 'com.google.protobuf:protoc:3.10.0' }
    plugins {
        javalite {
            artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0"
        }
        grpc {
            artifact = 'io.grpc:protoc-gen-grpc-java:1.25.0'
            // CURRENT_GRPC_VERSION
        }
    }
    generateProtoTasks {
        all().each { task ->
            task.plugins {
                javalite {}
                grpc {
                    // Options added to --grpc_out
                    option 'lite'
                }
            }
        }
    }
}
dependencies {
...........
    implementation 'io.grpc:grpc-protobuf-lite:1.25.0'
...........

}


Step 3: 

Add below lines to your project level gradle file

buildscript {
  ...............
    
    dependencies {
......
        classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.8"
    }
}


Step 4: 

Once the proto files are placed and the required dependencies are added, you can view your request, response and the other grpc related code in files generated from proto files which the same proto file names in build folder


Step 5: 

The input of grpc is ready and now time for the implementation on using it, as Grpc is used for streaming data continuously its better to run it in thread, create a Kotlin class

abstract class GrpcStatistics(private val mRequest: StatisticsRequest) : Runnable {

    private var backgroundThread: Thread? = null
    @Volatile
    private var mIsRunning: Boolean? = false
    private var mChannel: ManagedChannel? = null

    val isRunning: Boolean?
        get() = mIsRunning!! && backgroundThread == null

    @Synchronized
    fun start() {
        if (isRunning==false) {
            if (backgroundThread == null) {
                backgroundThread = Thread(this)
                backgroundThread!!.start()
            }
            mIsRunning = true
        }
    }

    @Synchronized
    fun stop() {
        if (isRunning== false) {
            mIsRunning = false
            if (backgroundThread != null)
                backgroundThread!!.interrupt()
        }
    }

    override fun run() {
        try {
            mChannel = GrpcHelper.getManagedChannel(Constants.GRPC_HOST, Constants.GRPC_PORT) // Here goes your grpc host and port name 

//            In case you need to pass the header to access grpc services

            val header = HashMap<String, Any>()
            header[Constants.HEADER_KEY_AUTHORIZATION] = mAuthKey
            header[Constants.HEADER_KEY_CONTENT_TYPE] = Constants.HEADER_VAL_CONTENT_TYPE


            while (mIsRunning!!) {
                val response = GrpcHelper.getStatistics(mChannel!!, header, mRequest) // This is where you get the response and you can handle it accordingly, Grpc helper is provided in the next step 
                while (mIsRunning!! && response.hasNext()) {
                    val statisticsResponse = response.next()
                    if (statisticsResponse != null) {
                        notifyStatisticsResponse(statisticsResponse)
                    }
                }
                try {
                    Thread.sleep(1000)
                } catch (e: Exception) {
                }

            }
        } catch (e: Exception) {

            e.printStackTrace()
        } finally {
            channelShutdown()
            backgroundThread = null
        }
    }

    private fun channelShutdown() {
        try {
            if (mChannel != null) {
                mChannel!!.shutdown().awaitTermination(200, TimeUnit.MILLISECONDS)
            }
        } catch (e: Exception) {

        }

    }

    abstract fun onResponse(statisticsResponse: StatisticsResponse)

    @Synchronized
    private fun notifyStatisticsResponse(statisticsResponse: StatisticsResponse) {
        onResponse(statisticsResponse)
    }

    companion object {
        private val TAG = "GrpcResponse"
    }
}


Step 6: 

Create a GRPCHelper kotlin class, a common class to maintain all the request and response from the grpc proto files

fun getStatistics(channel: ManagedChannel, header: Map<String, Any>, statisticsRequest: StatisticsRequest): Iterator<StatisticsResponse> {
        var stub = StatisticsServiceGrpc.newBlockingStub(channel)
        stub = MetadataUtils.attachHeaders(stub, getMetadata(header))
        return stub.getStatistics(statisticsRequest)
    } 

Step 7:

Finally how do you call this from your main class

 private var stathandler: Handler? = null
 private var mGrpcStatistics: GrpcStatistics? = null

// Inorder to initiate the grpc call this method
    private fun initstatisticsResponse() {

        stathandler = Handler()
        activityReference = WeakReference<Activity>(activity)

        val statisticsBuilder = StatisticsRequest.newBuilder()
     
            val dataRequired  = .... //refer the proto files request generated in your build files and send the  //           data if the request accepts any data
            statisticsBuilder.addData(dataRequired!!)
        }

        val statisticsRequest = statisticsBuilder.build()

        mGrpcStatistics = object : GrpcStatistics(statisticsRequest) {
            override fun onResponse(statisticsResponse: StatisticsResponse) {
                activity!!.runOnUiThread {
                    updateResponse(statisticsResponse) // Receive the response of grpc updated periodically //                      and bind the data accordingly 
                }
            }

        }
        mGrpcStatistics!!.start()

    }


Step 8:

Initiate grpc and stop grpc


Initiate Grpc 
Call the method initstatisticsResponse() where you need to initate the grpc streaming


End the Grpc Streaming: 
Add the below lines to stop streaming
        
 wasActivityResumed = true
        if (mGrpcStatistics != null) {
           mGrpcStatistics!!.stop()
        }


Please do share your thoughts and any queries on this post in the comments below and please do like the post by giving +1 and  by sharing it. 

Post a Comment

0 Comments