Fix websocket communication front logic closing too early
This commit is contained in:
parent
72c7f111e8
commit
b7b42a8c6d
8 changed files with 111 additions and 90 deletions
39
Cargo.lock
generated
39
Cargo.lock
generated
|
@ -68,17 +68,6 @@ version = "1.0.71"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
|
checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "async-channel"
|
|
||||||
version = "1.9.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35"
|
|
||||||
dependencies = [
|
|
||||||
"concurrent-queue",
|
|
||||||
"event-listener",
|
|
||||||
"futures-core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-lock"
|
name = "async-lock"
|
||||||
version = "2.7.0"
|
version = "2.7.0"
|
||||||
|
@ -197,15 +186,6 @@ dependencies = [
|
||||||
"generic-array",
|
"generic-array",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "concurrent-queue"
|
|
||||||
version = "2.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c"
|
|
||||||
dependencies = [
|
|
||||||
"crossbeam-utils",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "console_error_panic_hook"
|
name = "console_error_panic_hook"
|
||||||
version = "0.1.7"
|
version = "0.1.7"
|
||||||
|
@ -251,15 +231,6 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "crossbeam-utils"
|
|
||||||
version = "0.8.16"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ctr"
|
name = "ctr"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
|
@ -557,9 +528,9 @@ checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gloo-net"
|
name = "gloo-net"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3000ef231a67d5bfee6b35f2c0f6f5c8d45b3381ef5bbbea603690ec4e539762"
|
checksum = "8ac9e8288ae2c632fa9f8657ac70bfe38a1530f345282d7ba66a1f70b72b7dc4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
@ -578,9 +549,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gloo-utils"
|
name = "gloo-utils"
|
||||||
version = "0.1.7"
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "037fcb07216cb3a30f7292bd0176b050b7b9a052ba830ef7d5d65f6dc64ba58e"
|
checksum = "0b5555354113b18c547c1d3a98fbf7fb32a9ff4f6fa112ce823a21641a0ba3aa"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -1593,10 +1564,10 @@ dependencies = [
|
||||||
name = "usdpl-front"
|
name = "usdpl-front"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-channel",
|
|
||||||
"console_error_panic_hook",
|
"console_error_panic_hook",
|
||||||
"console_log",
|
"console_log",
|
||||||
"futures",
|
"futures",
|
||||||
|
"futures-channel",
|
||||||
"gloo-net",
|
"gloo-net",
|
||||||
"hex",
|
"hex",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
|
|
|
@ -10,6 +10,8 @@ exclude = [
|
||||||
"templates/decky/backend"
|
"templates/decky/backend"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
resolver = "2"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
# Tell `rustc` to optimize for small code size.
|
# Tell `rustc` to optimize for small code size.
|
||||||
opt-level = "s"
|
opt-level = "s"
|
||||||
|
|
|
@ -98,7 +98,7 @@ impl WebsocketServer {
|
||||||
RatchetError::with_cause(ratchet_rs::ErrorKind::Protocol, e.to_string())
|
RatchetError::with_cause(ratchet_rs::ErrorKind::Protocol, e.to_string())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
output_stream.for_each_concurrent(None, |result| async {
|
output_stream.for_each(|result| async {
|
||||||
match result {
|
match result {
|
||||||
Ok(msg) => {
|
Ok(msg) => {
|
||||||
let mut ws_lock = websocket.lock().await;
|
let mut ws_lock = websocket.lock().await;
|
||||||
|
@ -112,6 +112,11 @@ impl WebsocketServer {
|
||||||
}
|
}
|
||||||
}).await;
|
}).await;
|
||||||
|
|
||||||
|
websocket.lock().await.close(ratchet_rs::CloseReason {
|
||||||
|
code: ratchet_rs::CloseCode::Normal,
|
||||||
|
description: None,
|
||||||
|
}).await?;
|
||||||
|
|
||||||
/*let mut buf = BytesMut::new();
|
/*let mut buf = BytesMut::new();
|
||||||
loop {
|
loop {
|
||||||
match websocket.read(&mut buf).await? {
|
match websocket.read(&mut buf).await? {
|
||||||
|
|
|
@ -20,8 +20,9 @@ encrypt = ["usdpl-core/encrypt", "obfstr", "hex"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wasm-bindgen = "0.2"
|
wasm-bindgen = "0.2"
|
||||||
wasm-bindgen-futures = "0.4"
|
wasm-bindgen-futures = "0.4"
|
||||||
gloo-net = { version = "0.3", features = ["websocket"] }
|
gloo-net = { version = "0.4", features = ["websocket"] }
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
|
futures-channel = "0.3"
|
||||||
console_log = { version = "1.0", optional = true, features = ["color"] }
|
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
|
||||||
|
@ -37,11 +38,10 @@ web-sys = { version = "0.3", features = [
|
||||||
'RequestMode',
|
'RequestMode',
|
||||||
'Response',
|
'Response',
|
||||||
'Window',
|
'Window',
|
||||||
|
'console',
|
||||||
]}
|
]}
|
||||||
js-sys = { version = "0.3" }
|
js-sys = { version = "0.3" }
|
||||||
|
|
||||||
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 }
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::sync::atomic::{AtomicU64, Ordering};
|
use std::sync::atomic::{AtomicU64, Ordering};
|
||||||
|
|
||||||
use futures::{SinkExt, StreamExt, future::{select, Either}};
|
use futures::{SinkExt, StreamExt, future::{select, Either}};
|
||||||
use gloo_net::websocket::{futures::WebSocket, Message, State};
|
use gloo_net::websocket::{futures::WebSocket, Message};
|
||||||
use nrpc::{ClientHandler, ServiceError, ServiceClientStream, _helpers::async_trait, _helpers::bytes};
|
use nrpc::{ClientHandler, ServiceError, ServiceClientStream, _helpers::async_trait, _helpers::bytes};
|
||||||
use wasm_bindgen_futures::spawn_local;
|
use wasm_bindgen_futures::spawn_local;
|
||||||
|
|
||||||
|
@ -13,23 +13,42 @@ pub struct WebSocketHandler {
|
||||||
port: u16,
|
port: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_recv_ws<'a>(tx: async_channel::Sender<Result<bytes::Bytes, String>>, url: String, mut input: ServiceClientStream<'a, bytes::Bytes>) {
|
#[inline]
|
||||||
let ws = match WebSocket::open(&url).map_err(|e| e.to_string()) {
|
fn ws_is_alive(ws_state: &gloo_net::websocket::State) -> bool {
|
||||||
|
match ws_state {
|
||||||
|
gloo_net::websocket::State::Connecting | gloo_net::websocket::State::Open => true,
|
||||||
|
gloo_net::websocket::State::Closing | gloo_net::websocket::State::Closed => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn send_recv_ws<'a>(mut tx: futures_channel::mpsc::Sender<Result<bytes::Bytes, String>>, url: String, mut input: ServiceClientStream<'a, bytes::Bytes>) {
|
||||||
|
let ws = match WebSocket::open_with_protocol(&url, "usdpl-nrpc").map_err(|e| e.to_string()) {
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
log::error!("ws open error: {}", e);
|
||||||
tx.send(Err(e.to_string())).await.unwrap_or(());
|
tx.send(Err(e.to_string())).await.unwrap_or(());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
|
web_sys::console::log_1(&format!("ws opened successfully with url `{}`", url).into());
|
||||||
|
|
||||||
let (mut input_done, mut output_done) = (false, false);
|
let (mut input_done, mut output_done) = (false, false);
|
||||||
let mut last_ws_state = ws.state();
|
let mut last_ws_state = ws.state();
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
|
web_sys::console::log_1(&format!("ws with url `{}` initial state: {:?}", url, last_ws_state).into());
|
||||||
let (mut ws_sink, mut ws_stream) = ws.split();
|
let (mut ws_sink, mut ws_stream) = ws.split();
|
||||||
let (mut left, mut right) = (input.next(), ws_stream.next());
|
let (mut left, mut right) = (input.next(), ws_stream.next());
|
||||||
while let State::Open = last_ws_state {
|
while ws_is_alive(&last_ws_state) {
|
||||||
if !input_done && !output_done {
|
if !input_done && !output_done {
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
|
web_sys::console::debug_1(&format!("Input and output streams are both alive").into());
|
||||||
match select(left, right).await {
|
match select(left, right).await {
|
||||||
Either::Left((next, outstanding)) => {
|
Either::Left((next, outstanding)) => {
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
|
web_sys::console::debug_1(&format!("Got message to send over websocket").into());
|
||||||
if let Some(next) = next {
|
if let Some(next) = next {
|
||||||
match next {
|
match next {
|
||||||
Ok(next) => {
|
Ok(next) => {
|
||||||
|
@ -46,6 +65,8 @@ async fn send_recv_ws<'a>(tx: async_channel::Sender<Result<bytes::Bytes, String>
|
||||||
left = input.next();
|
left = input.next();
|
||||||
},
|
},
|
||||||
Either::Right((response, outstanding)) => {
|
Either::Right((response, outstanding)) => {
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
|
web_sys::console::debug_1(&format!("Received message from websocket").into());
|
||||||
if let Some(next) = response {
|
if let Some(next) = response {
|
||||||
match next {
|
match next {
|
||||||
Ok(Message::Bytes(b)) => tx.send(Ok(b.into())).await.unwrap_or(()),
|
Ok(Message::Bytes(b)) => tx.send(Ok(b.into())).await.unwrap_or(()),
|
||||||
|
@ -63,7 +84,11 @@ async fn send_recv_ws<'a>(tx: async_channel::Sender<Result<bytes::Bytes, String>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if input_done {
|
} else if input_done {
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
|
web_sys::console::debug_1(&format!("Input stream is complete").into());
|
||||||
if let Some(next) = right.await {
|
if let Some(next) = right.await {
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
|
web_sys::console::debug_1(&format!("Received message from websocket").into());
|
||||||
match next {
|
match next {
|
||||||
Ok(Message::Bytes(b)) => tx.send(Ok(b.into())).await.unwrap_or(()),
|
Ok(Message::Bytes(b)) => tx.send(Ok(b.into())).await.unwrap_or(()),
|
||||||
Ok(_) => tx.send(Err("Message::Text not allowed".into())).await.unwrap_or(()),
|
Ok(_) => tx.send(Err("Message::Text not allowed".into())).await.unwrap_or(()),
|
||||||
|
@ -78,9 +103,34 @@ async fn send_recv_ws<'a>(tx: async_channel::Sender<Result<bytes::Bytes, String>
|
||||||
(ws_sink, ws_stream) = ws.split();
|
(ws_sink, ws_stream) = ws.split();
|
||||||
right = ws_stream.next();
|
right = ws_stream.next();
|
||||||
} else {
|
} else {
|
||||||
|
// output_done is true
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
|
web_sys::console::debug_1(&format!("Output stream is complete").into());
|
||||||
|
if let Some(next) = left.await {
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
|
web_sys::console::debug_1(&format!("Got message to send over websocket").into());
|
||||||
|
match next {
|
||||||
|
Ok(next) => {
|
||||||
|
if let Err(e) = ws_sink.send(Message::Bytes(next.into())).await {
|
||||||
|
tx.send(Err(e.to_string())).await.unwrap_or(());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => tx.send(Err(e.to_string())).await.unwrap_or(())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
input_done = true;
|
||||||
|
}
|
||||||
|
//right = outstanding;
|
||||||
|
let ws = ws_stream.reunite(ws_sink).unwrap();
|
||||||
|
last_ws_state = ws.state();
|
||||||
|
(ws_sink, ws_stream) = ws.split();
|
||||||
|
left = input.next();
|
||||||
|
right = ws_stream.next(); // this should always resolve to None (but compiler is unhappy without this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
|
web_sys::console::debug_1(&format!("ws with url `{}` has closed", url).into());
|
||||||
/*spawn_local(async move {
|
/*spawn_local(async move {
|
||||||
while let State::Open = ws.state() {
|
while let State::Open = ws.state() {
|
||||||
if let Some(next) = input.next().await {
|
if let Some(next) = input.next().await {
|
||||||
|
@ -147,7 +197,9 @@ impl ClientHandler<'static> for WebSocketHandler {
|
||||||
"ws://usdpl-ws-{}.localhost:{}/{}.{}/{}",
|
"ws://usdpl-ws-{}.localhost:{}/{}.{}/{}",
|
||||||
id, self.port, package, service, method,
|
id, self.port, package, service, method,
|
||||||
);
|
);
|
||||||
let (tx, rx) = async_channel::bounded(CHANNEL_BOUND);
|
#[cfg(feature = "debug")]
|
||||||
|
web_sys::console::log_1(&format!("doing send/receive on ws url `{}`", url).into());
|
||||||
|
let (tx, rx) = futures_channel::mpsc::channel(CHANNEL_BOUND);
|
||||||
spawn_local(send_recv_ws(tx, url, input));
|
spawn_local(send_recv_ws(tx, url, input));
|
||||||
|
|
||||||
Ok(Box::new(rx.map(|buf_result: Result<bytes::Bytes, String>| buf_result
|
Ok(Box::new(rx.map(|buf_result: Result<bytes::Bytes, String>| buf_result
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use js_sys::JsString;
|
//use js_sys::JsString;
|
||||||
use js_sys::JSON::{parse, stringify};
|
//use js_sys::JSON::{parse, stringify};
|
||||||
use wasm_bindgen::prelude::JsValue;
|
use wasm_bindgen::prelude::JsValue;
|
||||||
|
|
||||||
use usdpl_core::serdes::Primitive;
|
//use usdpl_core::serdes::Primitive;
|
||||||
|
|
||||||
pub(crate) fn primitive_to_js(primitive: Primitive) -> JsValue {
|
/*pub(crate) fn primitive_to_js(primitive: Primitive) -> JsValue {
|
||||||
match primitive {
|
match primitive {
|
||||||
Primitive::Empty => JsValue::null(),
|
Primitive::Empty => JsValue::null(),
|
||||||
Primitive::String(s) => JsValue::from_str(&s),
|
Primitive::String(s) => JsValue::from_str(&s),
|
||||||
|
@ -33,11 +33,11 @@ pub(crate) fn js_to_primitive(val: JsValue) -> Primitive {
|
||||||
} else {
|
} else {
|
||||||
Primitive::Empty
|
Primitive::Empty
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
pub(crate) fn str_to_js<S: std::string::ToString>(s: S) -> JsString {
|
/*pub(crate) fn str_to_js<S: std::string::ToString>(s: S) -> JsString {
|
||||||
s.to_string().into()
|
s.to_string().into()
|
||||||
}
|
}*/
|
||||||
|
|
||||||
pub(crate) fn js_to_str(js: JsValue) -> String {
|
pub(crate) fn js_to_str(js: JsValue) -> String {
|
||||||
if let Some(s) = js.as_string() {
|
if let Some(s) = js.as_string() {
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
use wasm_bindgen::prelude::*;
|
|
||||||
|
|
||||||
#[wasm_bindgen]
|
|
||||||
extern "C" {
|
|
||||||
#[cfg(feature = "debug")]
|
|
||||||
#[wasm_bindgen(js_namespace = console, js_name = log)]
|
|
||||||
pub fn console_log(s: &str);
|
|
||||||
|
|
||||||
#[cfg(feature = "debug")]
|
|
||||||
#[wasm_bindgen(js_namespace = console, js_name = warn)]
|
|
||||||
pub fn console_warn(s: &str);
|
|
||||||
|
|
||||||
#[cfg(feature = "debug")]
|
|
||||||
#[wasm_bindgen(js_namespace = console, js_name = error)]
|
|
||||||
pub fn console_error(s: &str);
|
|
||||||
}
|
|
|
@ -7,9 +7,8 @@
|
||||||
|
|
||||||
mod client_handler;
|
mod client_handler;
|
||||||
pub use client_handler::WebSocketHandler;
|
pub use client_handler::WebSocketHandler;
|
||||||
mod connection;
|
//mod connection;
|
||||||
mod convert;
|
mod convert;
|
||||||
mod imports;
|
|
||||||
pub mod wasm;
|
pub mod wasm;
|
||||||
|
|
||||||
/*#[allow(missing_docs)] // existence is pain otherwise
|
/*#[allow(missing_docs)] // existence is pain otherwise
|
||||||
|
@ -27,21 +26,21 @@ pub mod _helpers {
|
||||||
pub use nrpc;
|
pub use nrpc;
|
||||||
}
|
}
|
||||||
|
|
||||||
use std::sync::atomic::{AtomicU64, Ordering};
|
//use std::sync::atomic::{AtomicU64, Ordering};
|
||||||
|
|
||||||
use js_sys::Array;
|
//use js_sys::Array;
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
use usdpl_core::{socket::Packet, RemoteCall};
|
//use usdpl_core::{socket::Packet, RemoteCall};
|
||||||
//const REMOTE_CALL_ID: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
|
//const REMOTE_CALL_ID: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
|
||||||
//const REMOTE_PORT: std::sync::atomic::AtomicU16 = std::sync::atomic::AtomicU16::new(31337);
|
//const REMOTE_PORT: std::sync::atomic::AtomicU16 = std::sync::atomic::AtomicU16::new(31337);
|
||||||
|
|
||||||
static mut CTX: UsdplContext = UsdplContext {
|
/*static mut CTX: UsdplContext = UsdplContext {
|
||||||
port: 0,
|
port: 0,
|
||||||
id: AtomicU64::new(0),
|
//id: AtomicU64::new(0),
|
||||||
#[cfg(feature = "encrypt")]
|
#[cfg(feature = "encrypt")]
|
||||||
key: Vec::new(),
|
key: Vec::new(),
|
||||||
};
|
};*/
|
||||||
|
|
||||||
static mut CACHE: Option<std::collections::HashMap<String, JsValue>> = None;
|
static mut CACHE: Option<std::collections::HashMap<String, JsValue>> = None;
|
||||||
|
|
||||||
|
@ -52,6 +51,7 @@ fn encryption_key() -> Vec<u8> {
|
||||||
hex::decode(obfstr::obfstr!(env!("USDPL_ENCRYPTION_KEY"))).unwrap()
|
hex::decode(obfstr::obfstr!(env!("USDPL_ENCRYPTION_KEY"))).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
//#[wasm_bindgen]
|
//#[wasm_bindgen]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct UsdplContext {
|
struct UsdplContext {
|
||||||
|
@ -68,33 +68,39 @@ fn get_port() -> u16 {
|
||||||
#[cfg(feature = "encrypt")]
|
#[cfg(feature = "encrypt")]
|
||||||
fn get_key() -> Vec<u8> {
|
fn get_key() -> Vec<u8> {
|
||||||
unsafe { CTX.key.clone() }
|
unsafe { CTX.key.clone() }
|
||||||
}
|
}*/
|
||||||
|
|
||||||
fn increment_id() -> u64 {
|
/*fn increment_id() -> u64 {
|
||||||
let atomic = unsafe { &CTX.id };
|
let atomic = unsafe { &CTX.id };
|
||||||
atomic.fetch_add(1, Ordering::SeqCst)
|
atomic.fetch_add(1, Ordering::SeqCst)
|
||||||
}
|
}*/
|
||||||
|
|
||||||
/// Initialize the front-end library
|
/// Initialize the front-end library
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn init_usdpl(port: u16) {
|
pub fn init_usdpl(port: u16) {
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
|
web_sys::console::log_1(&format!("init_usdpl(port={})", port).into());
|
||||||
#[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")]
|
#[cfg(feature = "console_log")]
|
||||||
console_log::init_with_level(log::Level::Debug).expect("USDPL: error initializing 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);
|
|
||||||
unsafe {
|
/*unsafe {
|
||||||
CTX = UsdplContext {
|
CTX = UsdplContext {
|
||||||
port: port,
|
port: port,
|
||||||
id: AtomicU64::new(0),
|
//id: AtomicU64::new(0),
|
||||||
#[cfg(feature = "encrypt")]
|
#[cfg(feature = "encrypt")]
|
||||||
key: encryption_key(),
|
key: encryption_key(),
|
||||||
};
|
};
|
||||||
}
|
}*/
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
CACHE = Some(std::collections::HashMap::new());
|
CACHE = Some(std::collections::HashMap::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
|
web_sys::console::log_1(&format!("USDPL:{} init succeeded", port).into());
|
||||||
|
log::info!("USDPL:{} init succeeded", port);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the targeted plugin framework, or "any" if unknown
|
/// Get the targeted plugin framework, or "any" if unknown
|
||||||
|
@ -134,16 +140,17 @@ pub fn get_value(key: String) -> JsValue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
/// Call a function on the back-end.
|
/// Call a function on the back-end.
|
||||||
/// Returns null (None) if this fails for any reason.
|
/// Returns null (None) if this fails for any reason.
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub async fn call_backend(name: String, parameters: Vec<JsValue>) -> JsValue {
|
pub async fn call_backend(name: String, parameters: Vec<JsValue>) -> JsValue {
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
imports::console_log(&format!(
|
web_sys::console::log_1(&format!(
|
||||||
"call_backend({}, [params; {}])",
|
"call_backend({}, [params; {}])",
|
||||||
name,
|
name,
|
||||||
parameters.len()
|
parameters.len()
|
||||||
));
|
).into());
|
||||||
let next_id = increment_id();
|
let next_id = increment_id();
|
||||||
let mut params = Vec::with_capacity(parameters.len());
|
let mut params = Vec::with_capacity(parameters.len());
|
||||||
for val in parameters {
|
for val in parameters {
|
||||||
|
@ -151,7 +158,7 @@ pub async fn call_backend(name: String, parameters: Vec<JsValue>) -> JsValue {
|
||||||
}
|
}
|
||||||
let port = get_port();
|
let port = get_port();
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
imports::console_log(&format!("USDPL: Got port {}", port));
|
web_sys::console::log_1(&format!("USDPL: Got port {}", port).into());
|
||||||
let results = connection::send_call(
|
let results = connection::send_call(
|
||||||
next_id,
|
next_id,
|
||||||
Packet::Call(RemoteCall {
|
Packet::Call(RemoteCall {
|
||||||
|
@ -169,7 +176,7 @@ pub async fn call_backend(name: String, parameters: Vec<JsValue>) -> JsValue {
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
imports::console_error(&format!("USDPL: Got error while calling {}: {:?}", name, e));
|
web_sys::console::error_1(&format!("USDPL: Got error while calling {}: {:?}", name, e).into());
|
||||||
return JsValue::NULL;
|
return JsValue::NULL;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -197,7 +204,7 @@ pub async fn init_tr(locale: String) {
|
||||||
{
|
{
|
||||||
Ok(Packet::Translations(translations)) => {
|
Ok(Packet::Translations(translations)) => {
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
imports::console_log(&format!("USDPL: Got translations for {}", locale));
|
web_sys::console::log_1(&format!("USDPL: Got translations for {}", locale).into());
|
||||||
// convert translations into map
|
// convert translations into map
|
||||||
let mut tr_map = std::collections::HashMap::with_capacity(translations.len());
|
let mut tr_map = std::collections::HashMap::with_capacity(translations.len());
|
||||||
for (key, val) in translations {
|
for (key, val) in translations {
|
||||||
|
@ -207,17 +214,17 @@ pub async fn init_tr(locale: String) {
|
||||||
}
|
}
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
imports::console_error(&format!("USDPL: Got wrong packet response for init_tr"));
|
web_sys::console::error_1(&format!("USDPL: Got wrong packet response for init_tr").into());
|
||||||
unsafe { TRANSLATIONS = None }
|
unsafe { TRANSLATIONS = None }
|
||||||
}
|
}
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
imports::console_error(&format!("USDPL: Got wrong error for init_tr: {:#?}", e));
|
web_sys::console::error_1(&format!("USDPL: Got wrong error for init_tr: {:#?}", e).into());
|
||||||
unsafe { TRANSLATIONS = None }
|
unsafe { TRANSLATIONS = None }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
/// Translate a phrase, equivalent to tr_n(msg_id, 0)
|
/// Translate a phrase, equivalent to tr_n(msg_id, 0)
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
|
|
Loading…
Reference in a new issue