use super::{Publisher, Subscriber};
use crate::setup;
use webtransport_quinn::{RecvStream, SendStream, Session};
use anyhow::Context;
pub struct Server {}
impl Server {
pub async fn accept(session: Session) -> anyhow::Result<Request> {
let mut control = session.accept_bi().await.context("failed to accept bidi stream")?;
let client = setup::Client::decode(&mut control.1)
.await
.context("failed to read CLIENT SETUP")?;
client
.versions
.iter()
.find(|version| **version == setup::Version::KIXEL_00)
.context("no supported versions")?;
Ok(Request {
session,
client,
control,
})
}
}
pub struct Request {
session: Session,
client: setup::Client,
control: (SendStream, RecvStream),
}
impl Request {
pub async fn publisher(mut self) -> anyhow::Result<Publisher> {
self.send_setup(setup::Role::Publisher).await?;
let publisher = Publisher::new(self.session, self.control);
Ok(publisher)
}
pub async fn subscriber(mut self) -> anyhow::Result<Subscriber> {
self.send_setup(setup::Role::Subscriber).await?;
let subscriber = Subscriber::new(self.session, self.control);
Ok(subscriber)
}
async fn send_setup(&mut self, role: setup::Role) -> anyhow::Result<()> {
let server = setup::Server {
role,
version: setup::Version::KIXEL_00,
};
if !self.client.role.is_compatible(server.role) {
anyhow::bail!(
"incompatible roles: client={:?} server={:?}",
self.client.role,
server.role
);
}
server
.encode(&mut self.control.0)
.await
.context("failed to send setup server")?;
Ok(())
}
pub fn reject(self, code: u32) {
self.session.close(code, b"")
}
pub fn role(&self) -> setup::Role {
self.client.role
}
}