Grpc Stream Kotlin Example
Integrate the below steps for the Grpc stream to work in AndroidStep 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 fileapply 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 filebuildscript {
...............
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 folderStep 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 classabstract 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 filesfun 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 classprivate 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 grpcInitiate 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.
0 Comments