Files
room_glitch/labs/glitch_odin/src/godot.rs
T

38 lines
1.6 KiB
Rust

//! Local JSON sidecar boundary; NATS/MessagePack remains in Rust.
use anyhow::{Context, Result};
use futures_util::StreamExt;
use glitch_odin_lab::*;
use tokio::{io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader}, net::TcpStream};
use std::time::Duration;
async fn forward(command: Command) -> Result<Reply> {
let mut stream = TcpStream::connect("127.0.0.1:18768").await?;
let mut bytes = serde_json::to_vec(&command)?;
bytes.push(b'\n');
stream.write_all(&bytes).await?;
let mut line = String::new();
BufReader::new(stream.take(65536)).read_line(&mut line).await?;
let reply: Reply = serde_json::from_str(&line)?;
anyhow::ensure!(!reply.state.simulated, "Expected real Godot cabinet");
Ok(reply)
}
pub async fn run(client: async_nats::Client) -> Result<()> {
let mut subscription = client.subscribe(SUBJECT).await?;
client.flush().await?;
println!("Godot sidecar ready: 127.0.0.1:18768; no simulated responder");
while let Some(message) = subscription.next().await {
if let Some(subject) = message.reply {
let result = async {
let command: Command = rmp_serde::from_slice(&message.payload)?;
tokio::time::timeout(Duration::from_millis(1500), forward(command))
.await.context("Godot reply timeout")?
}.await;
match result {
Ok(reply) => client.publish(subject, rmp_serde::to_vec_named(&reply)?.into()).await?,
Err(error) => eprintln!("Godot request unconfirmed: {error:#}"),
}
}
}
Ok(())
}