I am writing a simple app with Spring 5 Webflux and Kotlin. I am trying to implement PUT endpoint in a following way:
PUT(\"/confs/{id}\", {
val id = it.
WebClient.exchange()
result stream is unicastThe problem here is in fact that WebClient
allows only one subscriber per connection. If you try to subscribe to the same exchanged connection twice - you will get java.lang.IllegalStateException: Only one connection receive subscriber allowed.
Despite the fact that I don't see where you have tried to reuse the same connection twice, I believe that you may solve that problem by using next combination of operators:
class GeoService() {
val client = WebClient.create("https://maps.googleapis.com/maps/api/geocode/")
fun resolveGeoFromCity(city: String): Mono {
return client.get()
.uri("json?address=$city&key=$API_KEY&language=en")
.exchange()
.flatMap { it.bodyToMono(String::class.java) }
.map { parse(it) }
.share();
}
...
}
in that example, flow is configured to multicasts (shares) the original source as long as there is at least one Subscriber
will be subscribed.
In case if you need that all subscribers receive the same date you may replace .share
with .cache
operator.
Also, there is an alternative to above technique. You may replace mentioned operator with a processor and get the same sharing possibility:
class GeoService() {
val client = WebClient.create("https://maps.googleapis.com/maps/api/geocode/")
fun resolveGeoFromCity(city: String): Mono {
return client.get()
.uri("json?address=$city&key=$API_KEY&language=en")
.exchange()
.flatMap { it.bodyToMono(String::class.java) }
.map { parse(it) }
.subscribeWith(DirectProcessor.create());
}
...
}
In that case, you subscribing and running consumption of source's data exactly right after calling subscribeWith
, so, potentially, in that case, you may lose some part of data, etc.
Mono.just(..)
everything works fine?First of all .just
is a cold operator, it allows as many as possible subscribers which receive the same data at any point in time. That is why when you tried to consume the same chunk of data from the connection twice, you did not get any exceptions.