Request receiver
This commit is contained in:
+5
-16
@@ -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?;
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user