diff --git a/js/quad-ws.js b/js/quad-ws.js index 3512ef1..7523eae 100644 --- a/js/quad-ws.js +++ b/js/quad-ws.js @@ -25,14 +25,13 @@ const WS_DISCONNECTED = 0; const WS_CONNECTED = 1; const WS_CLOSED = 2; -function ws_open(ptr, len) { - let url = UTF8ToString(ptr, len); - let id = i++; +function ws_open_js(url, id) { let conn; try { conn = { socket: new WebSocket(url), - state: WS_DISCONNECTED, + url, + state: WS_CONNECTED, received: [] }; } catch (error) { @@ -46,17 +45,29 @@ function ws_open(ptr, len) { conn.received.push(new Uint8Array(e.data.arrayBuffer())); }; conn.socket.onerror = (s, e) => { - conn.state = WS_CLOSED; + conn.state = WS_DISCONNECTED; }; conn.socket.onclose = (s, e) => { - conn.state = WS_CLOSED; - delete ws[id]; - ws[id] = undefined; + conn.state = WS_DISCONNECTED; + //delete ws[id]; + //ws[id] = undefined; }; ws[id] = conn; return id; } +function ws_open(ptr, len) { + let url = UTF8ToString(ptr, len); + return ws_open_js(url, i++); +} + +function ws_revive(id) { + if (ws[id] == null) return false; + if (ws[id].state == WS_NOT_EXISTING || ws[id].state == WS_CLOSED) return false; + if (ws[id].state == WS_CONNECTED) return true; + return ws_open_js(ws[id].url, id) == id; +} + function ws_write(id, ptr, len) { let data = new Uint8Array(wasm_memory.buffer, ptr, len); /*let data = new Uint8Array(len); @@ -70,7 +81,7 @@ function ws_write(id, ptr, len) { return false; } function ws_available(id) { - if (ws[id] != null || ws[id].received.length == 0) return -1; + if (ws[id] == null || ws[id].received == null || ws[id].received.length == 0) return -1; return ws[id].received[0].length; } @@ -90,10 +101,12 @@ function ws_close(id) { if (ws[id] == null) return; ws[id].socket.close(); ws[id].state = WS_CLOSED; + ws[id] = { state: WS_CLOSED }; } function register_plugin(importObject) { importObject.env.ws_open = ws_open; + importObject.env.ws_revive = ws_revive; importObject.env.ws_write = ws_write; importObject.env.ws_read = ws_read; importObject.env.ws_available = ws_available; diff --git a/src/lib.rs b/src/lib.rs index 383c44d..b2e0b38 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,7 +10,6 @@ use pc::*; #[repr(i32)] pub enum QuadWsState { - WsNotExisting = -1, WsDisconnected = 0, WsConnected = 1, WsClosed = 2, @@ -21,7 +20,7 @@ pub struct QuadWs { impl QuadWs { pub fn new(url: String) -> Self { Self { - channel: ws_open_rust(url).unwrap(), + channel: ws_open_rust(url).unwrap() } } pub fn write(&mut self, data: Vec) -> bool { @@ -39,6 +38,9 @@ impl QuadWs { } false } + pub fn revive(&mut self){ + ws_revive_rust(&mut self.channel); + } pub fn state(&mut self) -> QuadWsState { let state = ws_state_rust(&mut self.channel); if state < 0 || state > 2 { diff --git a/src/pc.rs b/src/pc.rs index 7e78ad5..24ced68 100644 --- a/src/pc.rs +++ b/src/pc.rs @@ -3,59 +3,98 @@ use std::net::TcpStream; use websocket::{native_tls::TlsStream, sync::Client, ClientBuilder, OwnedMessage, WebSocketError}; enum WsClient { - None, + Closed, + Disconnected, Insecure(Client), Secure(Client>), } pub struct WsConnection { client: WsClient, - _url: String, + url: String, } pub type WsChannnel = WsConnection; pub fn ws_open_rust(url: String) -> Option { let secure = url.starts_with("wss"); - let builder = ClientBuilder::new("ws://127.0.0.1:7878"); + let builder = ClientBuilder::new(&url); if builder.is_err() { return None; } - let mut builder = builder.expect("Failed to expect none err"); + let mut builder: ClientBuilder<'_> = builder.expect("Failed to expect none err"); if secure { let connector = builder.connect_secure(None); if connector.is_err() { return Some(WsConnection { - client: WsClient::None, - _url: url, + client: WsClient::Disconnected, + url, }); } let client = connector.expect("Failed to expect none err"); client.set_nonblocking(true).unwrap(); return Some(WsConnection { client: WsClient::Secure(client), - _url: url, + url, }); } let connector = builder.connect_insecure(); if connector.is_err() { return Some(WsConnection { - client: WsClient::None, - _url: url, + client: WsClient::Disconnected, + url, }); } let client = connector.expect("Failed to expect none err"); client.set_nonblocking(true).unwrap(); return Some(WsConnection { client: WsClient::Insecure(client), - _url: url, + url, }); } +pub fn ws_revive_rust(socket: &mut WsChannnel) -> bool { + match &mut socket.client { + WsClient::Insecure(_) | WsClient::Secure(_) => { + return true; + } + _ => {} + } + let secure = socket.url.starts_with("wss"); + let builder = ClientBuilder::new(&socket.url); + if builder.is_err() { + return false; + } + let mut builder: ClientBuilder<'_> = builder.expect("Failed to expect previous none err"); + if secure { + let connector = builder.connect_secure(None); + if connector.is_err() { + socket.client = WsClient::Disconnected; + return true; + } + let client = connector.expect("Failed to expect none err"); + client.set_nonblocking(true).unwrap(); + socket.client = WsClient::Secure(client); + return true; + } + let connector = builder.connect_insecure(); + if connector.is_err() { + socket.client = WsClient::Disconnected; + return true; + } + let client = connector.expect("Failed to expect none err"); + client.set_nonblocking(true).unwrap(); + socket.client = WsClient::Insecure(client); + return true; +} + pub fn ws_write_raw(socket: &mut WsChannnel, data: OwnedMessage) -> bool { match &mut socket.client { - WsClient::None => { + WsClient::Closed => { + return false; + } + WsClient::Disconnected => { return false; } WsClient::Insecure(client) => { @@ -73,9 +112,10 @@ pub fn ws_write_rust(socket: &mut WsChannnel, data: Vec) -> bool { pub fn ws_read_rust(socket: &mut WsChannnel) -> Option> { let message: Result = match socket.client { - WsClient::None => Err(WebSocketError::NoDataAvailable), + WsClient::Closed => Err(WebSocketError::NoDataAvailable), WsClient::Insecure(ref mut client) => client.recv_message(), WsClient::Secure(ref mut client) => client.recv_message(), + WsClient::Disconnected => Err(WebSocketError::NoDataAvailable), }; match message { Ok(message) => match message { @@ -84,7 +124,7 @@ pub fn ws_read_rust(socket: &mut WsChannnel) -> Option> { return Some(data); } websocket::OwnedMessage::Close(_) => { - socket.client = WsClient::None; + socket.client = WsClient::Disconnected; } websocket::OwnedMessage::Ping(ping) => { let message = OwnedMessage::Pong(ping); @@ -95,7 +135,7 @@ pub fn ws_read_rust(socket: &mut WsChannnel) -> Option> { Err(ref e) => match e { WebSocketError::IoError(err) => if err.kind() == std::io::ErrorKind::WouldBlock {}, WebSocketError::NoDataAvailable => { - socket.client = WsClient::None; + socket.client = WsClient::Disconnected; } _ => {} }, @@ -105,28 +145,24 @@ pub fn ws_read_rust(socket: &mut WsChannnel) -> Option> { pub fn ws_close_rust(socket: &mut WsChannnel) { match &socket.client { - WsClient::None => {} + WsClient::Closed => {} WsClient::Insecure(client) => { client.shutdown().unwrap(); - socket.client = WsClient::None; + socket.client = WsClient::Closed; } WsClient::Secure(client) => { client.shutdown().unwrap(); - socket.client = WsClient::None; + socket.client = WsClient::Closed; } + WsClient::Disconnected => {} } } -pub fn ws_state_rust(socket: &mut WsChannnel) -> i32{ +pub fn ws_state_rust(socket: &mut WsChannnel) -> i32 { match &socket.client { - WsClient::None => { - 2 - } - WsClient::Insecure(_) => { - 1 - } - WsClient::Secure(_) => { - 1 - } + WsClient::Closed => 2, + WsClient::Insecure(_) => 1, + WsClient::Secure(_) => 1, + WsClient::Disconnected => 0, } -} \ No newline at end of file +} diff --git a/src/wasm.rs b/src/wasm.rs index d49d78b..d8024e8 100644 --- a/src/wasm.rs +++ b/src/wasm.rs @@ -4,6 +4,7 @@ pub type WsChannnel = i32; extern "C" { fn ws_open(ptr: *const i8, len: u32) -> WsChannnel; + fn ws_revive(id: WsChannnel) -> bool; fn ws_write(id: WsChannnel, ptr: *const u8, len: u32) -> bool; fn ws_read(id: WsChannnel, ptr: *const u8, len: u32); fn ws_available(id: WsChannnel) -> i32; @@ -21,6 +22,10 @@ pub fn ws_open_rust(url: String) -> Option { } } +pub fn ws_revive_rust(socket: &mut WsChannnel) -> bool { + return unsafe { ws_revive(*socket) }; +} + pub fn ws_write_rust(socket: &mut WsChannnel, data: Vec) -> bool { let buf = data.as_slice(); let succ = unsafe { ws_write(*socket, buf.as_ptr(), buf.len() as u32) }; @@ -41,7 +46,7 @@ pub fn ws_close_rust(socket: &mut WsChannnel) { unsafe { ws_close(*socket) }; } -pub fn ws_state_rust(socket: &mut WsChannnel) -> i32{ +pub fn ws_state_rust(socket: &mut WsChannnel) -> i32 { let state = unsafe { ws_state(*socket) }; return state; -} \ No newline at end of file +}