Request receiver

This commit is contained in:
2026-02-19 04:05:22 +01:00
parent 095903d327
commit 0940731bd1
3 changed files with 57 additions and 18 deletions
+5 -16
View File
@@ -1,8 +1,8 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use session_rs::{Method, session::Session, ws::Frame}; use session_rs::{Method, session::Session};
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
struct Data {} struct Data;
impl Method for Data { impl Method for Data {
const NAME: &'static str = "data"; const NAME: &'static str = "data";
@@ -14,23 +14,12 @@ impl Method for Data {
async fn main() -> session_rs::Result<()> { async fn main() -> session_rs::Result<()> {
let session = Session::connect("127.0.0.1:8080", "/").await?; let session = Session::connect("127.0.0.1:8080", "/").await?;
tokio::spawn({ session.start_receiver();
let session = session.clone();
async move {
loop {
match session.ws.read().await {
Ok(Frame::Text(text)) => {
println!("Server says: {}", text);
}
Ok(_) => {}
Err(_) => break,
}
}
}
});
session.request::<Data>(()).await?; session.request::<Data>(()).await?;
session.on::<Data>(|i, d| println!("Ok {i} {d:?}")).await;
tokio::time::sleep(tokio::time::Duration::from_millis(1000)).await; tokio::time::sleep(tokio::time::Duration::from_millis(1000)).await;
session.close().await?; session.close().await?;
+8
View File
@@ -12,6 +12,14 @@ pub trait Method {
type Response: Serialize + for<'de> Deserialize<'de>; type Response: Serialize + for<'de> Deserialize<'de>;
} }
pub struct GenericMethod;
impl Method for GenericMethod {
const NAME: &'static str = "generic_do_not_use";
type Request = serde_json::Value;
type Response = serde_json::Value;
}
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
WebSocket(ws::Error), WebSocket(ws::Error),
+44 -2
View File
@@ -1,9 +1,9 @@
use std::sync::Arc; use std::{collections::HashMap, sync::Arc};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tokio::sync::Mutex; use tokio::sync::Mutex;
use crate::{Method, ws::WebSocket}; use crate::{GenericMethod, Method, ws::WebSocket};
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "lowercase", tag = "type")] #[serde(rename_all = "lowercase", tag = "type")]
@@ -27,6 +27,7 @@ pub enum Message<M: Method> {
pub struct Session { pub struct Session {
pub ws: WebSocket, pub ws: WebSocket,
id: Arc<Mutex<u32>>, id: Arc<Mutex<u32>>,
methods: Arc<Mutex<HashMap<String, Box<dyn Fn(u32, serde_json::Value) + Send + Sync>>>>,
} }
impl Session { impl Session {
@@ -34,6 +35,7 @@ impl Session {
Self { Self {
ws: self.ws.clone(), ws: self.ws.clone(),
id: self.id.clone(), id: self.id.clone(),
methods: self.methods.clone(),
} }
} }
} }
@@ -43,6 +45,7 @@ impl Session {
Self { Self {
ws, ws,
id: Arc::new(Mutex::new(0)), id: Arc::new(Mutex::new(0)),
methods: Arc::new(Mutex::new(HashMap::new())),
} }
} }
@@ -51,6 +54,45 @@ impl Session {
} }
} }
impl Session {
pub fn start_receiver(&self) {
let s = self.clone();
tokio::spawn(async move {
loop {
match s.ws.read().await {
Ok(crate::ws::Frame::Text(text)) => {
let Ok(msg) = serde_json::from_str::<Message<GenericMethod>>(&text) else {
continue;
};
match msg {
Message::Request { id, method, data } => {
if let Some(m) = s.methods.lock().await.get(&method) {
(m)(id, data)
}
}
_ => {}
}
}
Ok(_) => {}
Err(_) => break,
}
}
});
}
pub async fn on<M: Method>(&self, handler: impl Fn(u32, M::Request) + Send + Sync + 'static) {
self.methods.lock().await.insert(
M::NAME.to_string(),
Box::new(move |id, value| {
if let Ok(req) = serde_json::from_value(value) {
(handler)(id, req)
}
}),
);
}
}
impl Session { impl Session {
pub async fn send<M: Method>(&self, data: &Message<M>) -> crate::Result<()> { pub async fn send<M: Method>(&self, data: &Message<M>) -> crate::Result<()> {
self.ws self.ws