Make front WS service immutable to avoid wasm-rust exceptions, add debug logging

This commit is contained in:
NGnius (Graham) 2023-06-28 22:21:56 -04:00
parent 4fed12d6d9
commit 68b7455c9e
7 changed files with 54 additions and 12 deletions

24
Cargo.lock generated
View file

@ -183,6 +183,17 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "console_log"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be8aed40e4edbf4d3b4431ab260b63fdc40f5780a4766824329ea0f1eefe3c0f"
dependencies = [
"log",
"wasm-bindgen",
"web-sys",
]
[[package]] [[package]]
name = "convert_case" name = "convert_case"
version = "0.4.0" version = "0.4.0"
@ -797,6 +808,8 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a"
[[package]] [[package]]
name = "nrpc" name = "nrpc"
version = "0.6.0" version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f41caeb65399490c6f68ab2527a833d6f2e9b0d7d5ffc4b062f1484b3fa61cd"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"bytes", "bytes",
@ -805,9 +818,7 @@ dependencies = [
[[package]] [[package]]
name = "nrpc" name = "nrpc"
version = "0.6.0" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f41caeb65399490c6f68ab2527a833d6f2e9b0d7d5ffc4b062f1484b3fa61cd"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"bytes", "bytes",
@ -818,7 +829,7 @@ dependencies = [
name = "nrpc-build" name = "nrpc-build"
version = "0.7.0" version = "0.7.0"
dependencies = [ dependencies = [
"nrpc 0.6.0", "nrpc 0.7.0",
"prettyplease 0.2.4", "prettyplease 0.2.4",
"proc-macro2", "proc-macro2",
"prost-build", "prost-build",
@ -1502,7 +1513,7 @@ dependencies = [
"gettext-ng", "gettext-ng",
"hex", "hex",
"log", "log",
"nrpc 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "nrpc 0.6.0",
"obfstr", "obfstr",
"prost", "prost",
"ratchet_rs", "ratchet_rs",
@ -1539,12 +1550,13 @@ version = "0.11.0"
dependencies = [ dependencies = [
"async-channel", "async-channel",
"console_error_panic_hook", "console_error_panic_hook",
"console_log",
"futures", "futures",
"gloo-net", "gloo-net",
"hex", "hex",
"js-sys", "js-sys",
"log", "log",
"nrpc 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "nrpc 0.7.0",
"obfstr", "obfstr",
"prost", "prost",
"usdpl-core", "usdpl-core",

View file

@ -46,7 +46,7 @@ impl WebsocketServer {
let tcp = TcpListener::bind(addr).await?; let tcp = TcpListener::bind(addr).await?;
while let Ok((stream, _addr_do_not_use)) = tcp.accept().await { while let Ok((stream, _addr_do_not_use)) = tcp.accept().await {
tokio::spawn(Self::connection_handler(self.services.clone(), stream)); tokio::spawn(error_logger("USDPL websocket server error", Self::connection_handler(self.services.clone(), stream)));
} }
Ok(()) Ok(())
@ -65,6 +65,7 @@ impl WebsocketServer {
services: ServiceRegistry<'static>, services: ServiceRegistry<'static>,
stream: TcpStream, stream: TcpStream,
) -> Result<(), RatchetError> { ) -> Result<(), RatchetError> {
log::debug!("connection_handler invoked!");
let upgraded = ratchet_rs::accept_with( let upgraded = ratchet_rs::accept_with(
stream, stream,
WebSocketConfig::default(), WebSocketConfig::default(),
@ -77,6 +78,8 @@ impl WebsocketServer {
let request_path = upgraded.request.uri().path(); let request_path = upgraded.request.uri().path();
log::debug!("accepted new connection on uri {}", request_path);
let mut websocket = upgraded.websocket; let mut websocket = upgraded.websocket;
let descriptor = Self::parse_uri_path(request_path) let descriptor = Self::parse_uri_path(request_path)
@ -92,6 +95,7 @@ impl WebsocketServer {
)) ))
} }
Message::Binary => { Message::Binary => {
log::debug!("got binary ws message on uri {}", request_path);
let response = services let response = services
.call_descriptor( .call_descriptor(
descriptor.service, descriptor.service,
@ -102,6 +106,7 @@ impl WebsocketServer {
.map_err(|e| { .map_err(|e| {
RatchetError::with_cause(ratchet_rs::ErrorKind::Protocol, e.to_string()) RatchetError::with_cause(ratchet_rs::ErrorKind::Protocol, e.to_string())
})?; })?;
log::debug!("service completed response on uri {}", request_path);
websocket.write_binary(response).await?; websocket.write_binary(response).await?;
} }
Message::Ping(x) => websocket.write_pong(x).await?, Message::Ping(x) => websocket.write_pong(x).await?,
@ -109,11 +114,12 @@ impl WebsocketServer {
Message::Close(_) => break, Message::Close(_) => break,
} }
} }
log::debug!("ws connection {} closed", request_path);
Ok(()) Ok(())
} }
fn parse_uri_path<'a>(path: &'a str) -> Result<MethodDescriptor<'a>, &'static str> { fn parse_uri_path<'a>(path: &'a str) -> Result<MethodDescriptor<'a>, &'static str> {
let mut iter = path.split('/'); let mut iter = path.trim_matches('/').split('/');
if let Some(service) = iter.next() { if let Some(service) = iter.next() {
if let Some(method) = iter.next() { if let Some(method) = iter.next() {
if iter.next().is_none() { if iter.next().is_none() {
@ -129,3 +135,9 @@ impl WebsocketServer {
} }
} }
} }
async fn error_logger<E: std::error::Error>(msg: &'static str, f: impl core::future::Future<Output=Result<(), E>>) {
if let Err(e) = f.await {
log::error!("{}: {}", msg, e);
}
}

View file

@ -28,3 +28,18 @@ pub fn build(
.transpile() .transpile()
.unwrap() .unwrap()
} }
pub fn build_min(
custom_protos: impl Iterator<Item = String>,
custom_dirs: impl Iterator<Item = String>,
) {
crate::dump_protos_out().unwrap();
nrpc_build::Transpiler::new(
crate::all_proto_filenames(crate::proto_builtins_out_path(), custom_protos),
crate::proto_out_paths(custom_dirs),
)
.unwrap()
.generate_client()
.transpile()
.unwrap()
}

View file

@ -80,7 +80,7 @@ fn generate_service_methods(
gen_methods.push(quote::quote! { gen_methods.push(quote::quote! {
#[wasm_bindgen] #[wasm_bindgen]
pub async fn #method_name(&mut self, #(#input_params)*) -> Option<#method_output> { pub async fn #method_name(&self, #(#input_params)*) -> Option<#method_output> {
#params_to_fields_transformer #params_to_fields_transformer

View file

@ -14,7 +14,7 @@ crate-type = ["cdylib", "rlib"]
[features] [features]
default = [] default = []
decky = ["usdpl-core/decky"] decky = ["usdpl-core/decky"]
debug = ["console_error_panic_hook"] debug = ["console_error_panic_hook", "console_log"]
encrypt = ["usdpl-core/encrypt", "obfstr", "hex"] encrypt = ["usdpl-core/encrypt", "obfstr", "hex"]
[dependencies] [dependencies]
@ -22,6 +22,7 @@ wasm-bindgen = "0.2"
wasm-bindgen-futures = "0.4" wasm-bindgen-futures = "0.4"
gloo-net = { version = "0.2", features = ["websocket"] } gloo-net = { version = "0.2", features = ["websocket"] }
futures = "0.3" futures = "0.3"
console_log = { version = "1.0", optional = true, features = ["color"] }
# The `console_error_panic_hook` crate provides better debugging of panics by # The `console_error_panic_hook` crate provides better debugging of panics by
# logging them with `console.error`. This is great for development, but requires # logging them with `console.error`. This is great for development, but requires
@ -44,7 +45,7 @@ async-channel = "1.8"
obfstr = { version = "0.3", optional = true } obfstr = { version = "0.3", optional = true }
hex = { version = "0.4", optional = true } hex = { version = "0.4", optional = true }
nrpc = "0.6" nrpc = { version = "0.7", path = "../../nRPC/nrpc" }
usdpl-core = { version = "0.11", path = "../usdpl-core" } usdpl-core = { version = "0.11", path = "../usdpl-core" }
prost = "0.11" prost = "0.11"
log = "0.4" log = "0.4"

View file

@ -54,7 +54,7 @@ impl WebSocketHandler {
#[async_trait::async_trait] #[async_trait::async_trait]
impl ClientHandler for WebSocketHandler { impl ClientHandler for WebSocketHandler {
async fn call( async fn call(
&mut self, &self,
package: &str, package: &str,
service: &str, service: &str,
method: &str, method: &str,

View file

@ -78,6 +78,8 @@ fn increment_id() -> u64 {
pub fn init_usdpl(port: u16) { pub fn init_usdpl(port: u16) {
#[cfg(feature = "console_error_panic_hook")] #[cfg(feature = "console_error_panic_hook")]
console_error_panic_hook::set_once(); console_error_panic_hook::set_once();
#[cfg(feature = "console_log")]
console_log::init_with_level(log::Level::Debug).expect("USDPL: error initializing console log");
//REMOTE_PORT.store(port, std::sync::atomic::Ordering::SeqCst); //REMOTE_PORT.store(port, std::sync::atomic::Ordering::SeqCst);
unsafe { unsafe {
CTX = UsdplContext { CTX = UsdplContext {