1
1
package io.grpc.examples.routeguide
2
2
3
- import com.google.protobuf.util.JavaTimeConversions
4
3
import io.grpc.ManagedChannel
5
4
import io.grpc.ManagedChannelBuilder
6
5
import io.grpc.examples.routeguide.RouteGuideGrpcKt.RouteGuideCoroutineStub
7
- import java.io.Closeable
8
- import java.util.concurrent.Executors
9
- import java.util.concurrent.TimeUnit
10
- import kotlin.random.Random
11
- import kotlin.random.nextLong
12
6
import kotlinx.coroutines.CoroutineDispatcher
13
7
import kotlinx.coroutines.asCoroutineDispatcher
14
8
import kotlinx.coroutines.asExecutor
15
- import kotlinx.coroutines.async
16
- import kotlinx.coroutines.channels.Channel
17
9
import kotlinx.coroutines.delay
10
+ import kotlinx.coroutines.flow.asFlow
11
+ import kotlinx.coroutines.flow.collect
12
+ import kotlinx.coroutines.flow.flow
13
+ import kotlinx.coroutines.flow.onEach
18
14
import kotlinx.coroutines.launch
19
15
import kotlinx.coroutines.runBlocking
16
+ import java.io.Closeable
17
+ import java.util.concurrent.Executors
18
+ import java.util.concurrent.TimeUnit
19
+ import kotlin.random.Random
20
+ import kotlin.random.nextLong
20
21
21
22
class RouteGuideClient private constructor(
22
23
val channel : ManagedChannel ,
23
24
val stub : RouteGuideCoroutineStub ,
24
25
val printer : Printer
25
26
) : Closeable {
26
- val random = Random (314159 )
27
+ private val random = Random (314159 )
27
28
28
29
constructor (
29
30
channelBuilder: ManagedChannelBuilder <* >,
@@ -55,13 +56,18 @@ class RouteGuideClient private constructor(
55
56
}
56
57
}
57
58
}
59
+
60
+ private fun point (lat : Int , lon : Int ): Point =
61
+ Point .newBuilder()
62
+ .setLatitude(lat)
63
+ .setLongitude(lon)
64
+ .build()
58
65
}
59
66
60
67
override fun close () {
61
68
channel.shutdown().awaitTermination(5 , TimeUnit .SECONDS )
62
69
}
63
70
64
-
65
71
interface Printer {
66
72
companion object {
67
73
val stdout = object : Printer {
@@ -76,10 +82,10 @@ class RouteGuideClient private constructor(
76
82
fun getFeature (latitude : Int , longitude : Int ) = runBlocking {
77
83
printer.println (" *** GetFeature: lat=$latitude lon=$longitude " )
78
84
79
- val request = point {
80
- this . latitude = latitude
81
- this . longitude = longitude
82
- }
85
+ val request = Point .newBuilder()
86
+ .setLatitude( latitude)
87
+ .setLongitude( longitude)
88
+ .build()
83
89
val feature = stub.getFeature(request)
84
90
85
91
if (feature.exists()) {
@@ -92,90 +98,67 @@ class RouteGuideClient private constructor(
92
98
fun listFeatures (lowLat : Int , lowLon : Int , hiLat : Int , hiLon : Int ) = runBlocking {
93
99
printer.println (" *** ListFeatures: lowLat=$lowLat lowLon=$lowLon hiLat=$hiLat liLon=$hiLon " )
94
100
95
- val request = rectangle {
96
- lo = point {
97
- latitude = lowLat
98
- longitude = lowLon
99
- }
100
- hi = point {
101
- latitude = lowLat
102
- longitude = lowLon
103
- }
104
- }
101
+ val request = Rectangle .newBuilder()
102
+ .setLo(point(lowLat, lowLon))
103
+ .setHi(point(hiLat, hiLon))
104
+ .build()
105
105
var i = 1
106
- for (feature in stub.listFeatures(request)) {
107
- printer.println (" Result #$i : $feature " )
108
- i++
106
+ stub.listFeatures(request).collect { feature ->
107
+ printer.println (" Result #${i++ } : $feature " )
109
108
}
110
109
}
111
110
112
111
fun recordRoute (features : List <Feature >, numPoints : Int ) = runBlocking {
113
112
printer.println (" *** RecordRoute" )
114
- val requests = Channel <Point >()
113
+ val requests = flow {
114
+ for (i in 1 .. numPoints) {
115
+ val feature = features.random(random)
116
+ println (" Visiting point ${feature.location.toStr()} " )
117
+ emit(feature.location)
118
+ delay(timeMillis = random.nextLong(500L .. 1500L ))
119
+ }
120
+ }
115
121
val finish = launch {
116
122
val summary = stub.recordRoute(requests)
117
123
printer.println (" Finished trip with ${summary.pointCount} points." )
118
124
printer.println (" Passed ${summary.featureCount} features." )
119
125
printer.println (" Travelled ${summary.distance} meters." )
120
- val duration = JavaTimeConversions .toJavaDuration( summary.elapsedTime) .seconds
126
+ val duration = summary.elapsedTime.seconds
121
127
printer.println (" It took $duration seconds." )
122
128
}
123
- for (i in 1 .. numPoints) {
124
- val feature = features.random(random)
125
- println (" Visiting point ${feature.location.toStr()} " )
126
- requests.send(feature.location)
127
- delay(timeMillis = random.nextLong(500L .. 1500L ))
128
- }
129
- requests.close()
130
129
finish.join()
131
130
}
132
131
133
132
fun routeChat () = runBlocking {
134
133
printer.println (" *** RouteChat" )
135
- val requests = Channel <RouteNote >()
136
- val rpc = launch {
137
- val responses = stub.routeChat(requests)
138
- for (note in responses) {
139
- printer.println (" Got message \" ${note.message} \" at ${note.location.toStr()} " )
140
- }
141
- println (" Finished RouteChat" )
142
- }
143
134
val requestList = listOf (
144
- routeNote {
135
+ RouteNote .newBuilder(). apply {
145
136
message = " First message"
146
- location = point {
147
- latitude = 0
148
- longitude = 0
149
- }
150
- },
151
- routeNote {
137
+ location = point(0 , 0 )
138
+ }.build(),
139
+ RouteNote .newBuilder().apply {
152
140
message = " Second message"
153
- location = point {
154
- latitude = 0
155
- longitude = 1
156
- }
157
- },
158
- routeNote {
141
+ location = point(0 , 0 )
142
+ }.build(),
143
+ RouteNote .newBuilder().apply {
159
144
message = " Third message"
160
- location = point {
161
- latitude = 1
162
- longitude = 0
163
- }
164
- },
165
- routeNote {
145
+ location = point(1 , 0 )
146
+ }.build(),
147
+ RouteNote .newBuilder().apply {
166
148
message = " Fourth message"
167
- location = point {
168
- latitude = 1
169
- longitude = 1
170
- }
171
- }
149
+ location = point(1 , 1 )
150
+ }.build()
172
151
)
173
-
174
- for (request in requestList) {
152
+ val requests = requestList.asFlow().onEach { request ->
175
153
printer.println (" Sending message \" ${request.message} \" at ${request.location.toStr()} " )
176
- requests.send(request)
177
154
}
178
- requests.close()
155
+ val rpc = launch {
156
+ stub.routeChat(requests).collect { note ->
157
+ printer.println (" Got message \" ${note.message} \" at ${note.location.toStr()} " )
158
+ }
159
+ println (" Finished RouteChat" )
160
+ }
161
+
179
162
rpc.join()
180
163
}
181
164
}
0 commit comments