Replies
A reply named per request has no fixed channel, so the document points its address at the reply-to header of the request.
A responder answers on the response topic its request carries.
The crate maps that property onto the reply-to header, and a publish transform with Destination = Names reads it there.
The document is built before any request arrives, so it cannot name the topic.
The operation's reply.address.location is $message.header#/reply-to instead: a client reads the address of its answer from the header of its own request.
The mount-site name, reply("devices/dev42/pong"), is the reply channel the document reports, and where a request without a response topic is answered.
A reply that the type or the mount site names reports that channel alone.
Example
The operation receive_devices_dev42_ping reports "location": "$message.header#/reply-to" in its reply address.
- Macros
- Manual
/// Answers on the topic the request names in its response topic, the `reply-to` header.
struct ToResponseTopic;
impl<C, Options> PublishTransform<ForReply<C>, Options> for ToResponseTopic {
type Destination = Names;
fn apply(
&self,
out: &mut Outgoing<'_>,
_options: &mut Option<Options>,
cx: &PublishContext<'_, C>,
) {
if let Some(topic) = cx.headers().get_str("reply-to") {
out.set_name(topic.to_owned());
}
}
}
/// A request without a response topic is answered on `devices/dev42/pong`.
#[subscriber(MqttTopic::new("devices/dev42/ping"), reply("devices/dev42/pong"))]
async fn answer(ping: &Telemetry) -> Pong {
Pong {
device: ping.device.clone(),
}
}
/// Answers on the topic the request names in its response topic, the `reply-to` header.
struct ToResponseTopic;
impl<C, Options> PublishTransform<ForReply<C>, Options> for ToResponseTopic {
type Destination = Names;
fn apply(
&self,
out: &mut Outgoing<'_>,
_options: &mut Option<Options>,
cx: &PublishContext<'_, C>,
) {
if let Some(topic) = cx.headers().get_str("reply-to") {
out.set_name(topic.to_owned());
}
}
}