mirror of
https://github.com/MercuryWorkshop/epoxy-tls.git
synced 2025-05-17 08:00:02 -04:00
rewrite client
This commit is contained in:
parent
273063ec28
commit
177a0d2167
13 changed files with 1338 additions and 1710 deletions
174
client/src/io_stream.rs
Normal file
174
client/src/io_stream.rs
Normal file
|
@ -0,0 +1,174 @@
|
|||
use bytes::{BufMut, BytesMut};
|
||||
use futures_util::{
|
||||
io::WriteHalf, lock::Mutex, stream::SplitSink, AsyncReadExt, AsyncWriteExt, SinkExt, StreamExt,
|
||||
};
|
||||
use js_sys::{Function, Uint8Array};
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen_futures::spawn_local;
|
||||
|
||||
use crate::{
|
||||
stream_provider::{ProviderAsyncRW, ProviderUnencryptedStream},
|
||||
utils::convert_body,
|
||||
EpoxyError, EpoxyHandlers,
|
||||
};
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct EpoxyIoStream {
|
||||
tx: Mutex<WriteHalf<ProviderAsyncRW>>,
|
||||
onerror: Function,
|
||||
}
|
||||
|
||||
impl EpoxyIoStream {
|
||||
pub(crate) fn connect(stream: ProviderAsyncRW, handlers: EpoxyHandlers) -> Self {
|
||||
let (mut rx, tx) = stream.split();
|
||||
let tx = Mutex::new(tx);
|
||||
|
||||
let EpoxyHandlers {
|
||||
onopen,
|
||||
onclose,
|
||||
onerror,
|
||||
onmessage,
|
||||
} = handlers;
|
||||
|
||||
let onerror_cloned = onerror.clone();
|
||||
|
||||
// similar to tokio::io::ReaderStream
|
||||
spawn_local(async move {
|
||||
let mut buf = BytesMut::with_capacity(4096);
|
||||
loop {
|
||||
match rx.read(buf.as_mut()).await {
|
||||
Ok(cnt) => {
|
||||
unsafe { buf.advance_mut(cnt) };
|
||||
|
||||
let _ = onmessage
|
||||
.call1(&JsValue::null(), &Uint8Array::from(buf.split().as_ref()));
|
||||
}
|
||||
Err(err) => {
|
||||
let _ = onerror.call1(&JsValue::null(), &JsError::from(err).into());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
let _ = onclose.call0(&JsValue::null());
|
||||
});
|
||||
|
||||
let _ = onopen.call0(&JsValue::null());
|
||||
|
||||
Self {
|
||||
tx,
|
||||
onerror: onerror_cloned,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn send(&self, payload: JsValue) -> Result<(), EpoxyError> {
|
||||
let ret: Result<(), EpoxyError> = async move {
|
||||
let payload = convert_body(payload)
|
||||
.await
|
||||
.map_err(|_| EpoxyError::InvalidPayload)?
|
||||
.0
|
||||
.to_vec();
|
||||
Ok(self.tx.lock().await.write_all(&payload).await?)
|
||||
}
|
||||
.await;
|
||||
|
||||
match ret {
|
||||
Ok(ok) => Ok(ok),
|
||||
Err(err) => {
|
||||
let _ = self
|
||||
.onerror
|
||||
.call1(&JsValue::null(), &err.to_string().into());
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn close(&self) -> Result<(), EpoxyError> {
|
||||
match self.tx.lock().await.close().await {
|
||||
Ok(ok) => Ok(ok),
|
||||
Err(err) => {
|
||||
let _ = self
|
||||
.onerror
|
||||
.call1(&JsValue::null(), &err.to_string().into());
|
||||
Err(err.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct EpoxyUdpStream {
|
||||
tx: Mutex<SplitSink<ProviderUnencryptedStream, Vec<u8>>>,
|
||||
onerror: Function,
|
||||
}
|
||||
|
||||
impl EpoxyUdpStream {
|
||||
pub(crate) fn connect(stream: ProviderUnencryptedStream, handlers: EpoxyHandlers) -> Self {
|
||||
let (tx, mut rx) = stream.split();
|
||||
let tx = Mutex::new(tx);
|
||||
|
||||
let EpoxyHandlers {
|
||||
onopen,
|
||||
onclose,
|
||||
onerror,
|
||||
onmessage,
|
||||
} = handlers;
|
||||
|
||||
let onerror_cloned = onerror.clone();
|
||||
|
||||
spawn_local(async move {
|
||||
while let Some(packet) = rx.next().await {
|
||||
match packet {
|
||||
Ok(buf) => {
|
||||
let _ = onmessage.call1(&JsValue::null(), &Uint8Array::from(buf.as_ref()));
|
||||
}
|
||||
Err(err) => {
|
||||
let _ = onerror.call1(&JsValue::null(), &JsError::from(err).into());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
let _ = onclose.call0(&JsValue::null());
|
||||
});
|
||||
|
||||
let _ = onopen.call0(&JsValue::null());
|
||||
|
||||
Self {
|
||||
tx,
|
||||
onerror: onerror_cloned,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn send(&self, payload: JsValue) -> Result<(), EpoxyError> {
|
||||
let ret: Result<(), EpoxyError> = async move {
|
||||
let payload = convert_body(payload)
|
||||
.await
|
||||
.map_err(|_| EpoxyError::InvalidPayload)?
|
||||
.0
|
||||
.to_vec();
|
||||
Ok(self.tx.lock().await.send(payload).await?)
|
||||
}
|
||||
.await;
|
||||
|
||||
match ret {
|
||||
Ok(ok) => Ok(ok),
|
||||
Err(err) => {
|
||||
let _ = self
|
||||
.onerror
|
||||
.call1(&JsValue::null(), &err.to_string().into());
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn close(&self) -> Result<(), EpoxyError> {
|
||||
match self.tx.lock().await.close().await {
|
||||
Ok(ok) => Ok(ok),
|
||||
Err(err) => {
|
||||
let _ = self
|
||||
.onerror
|
||||
.call1(&JsValue::null(), &err.to_string().into());
|
||||
Err(err.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue