This commit is contained in:
jusax23 2023-10-02 14:09:07 +02:00
parent accec82a6a
commit 67e3c8275c
Signed by: jusax23
GPG key ID: 499E2AA870C1CD41
4 changed files with 97 additions and 41 deletions

View file

@ -25,14 +25,13 @@ const WS_DISCONNECTED = 0;
const WS_CONNECTED = 1; const WS_CONNECTED = 1;
const WS_CLOSED = 2; const WS_CLOSED = 2;
function ws_open(ptr, len) { function ws_open_js(url, id) {
let url = UTF8ToString(ptr, len);
let id = i++;
let conn; let conn;
try { try {
conn = { conn = {
socket: new WebSocket(url), socket: new WebSocket(url),
state: WS_DISCONNECTED, url,
state: WS_CONNECTED,
received: [] received: []
}; };
} catch (error) { } catch (error) {
@ -46,17 +45,29 @@ function ws_open(ptr, len) {
conn.received.push(new Uint8Array(e.data.arrayBuffer())); conn.received.push(new Uint8Array(e.data.arrayBuffer()));
}; };
conn.socket.onerror = (s, e) => { conn.socket.onerror = (s, e) => {
conn.state = WS_CLOSED; conn.state = WS_DISCONNECTED;
}; };
conn.socket.onclose = (s, e) => { conn.socket.onclose = (s, e) => {
conn.state = WS_CLOSED; conn.state = WS_DISCONNECTED;
delete ws[id]; //delete ws[id];
ws[id] = undefined; //ws[id] = undefined;
}; };
ws[id] = conn; ws[id] = conn;
return id; 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) { function ws_write(id, ptr, len) {
let data = new Uint8Array(wasm_memory.buffer, ptr, len); let data = new Uint8Array(wasm_memory.buffer, ptr, len);
/*let data = new Uint8Array(len); /*let data = new Uint8Array(len);
@ -70,7 +81,7 @@ function ws_write(id, ptr, len) {
return false; return false;
} }
function ws_available(id) { 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; return ws[id].received[0].length;
} }
@ -90,10 +101,12 @@ function ws_close(id) {
if (ws[id] == null) return; if (ws[id] == null) return;
ws[id].socket.close(); ws[id].socket.close();
ws[id].state = WS_CLOSED; ws[id].state = WS_CLOSED;
ws[id] = { state: WS_CLOSED };
} }
function register_plugin(importObject) { function register_plugin(importObject) {
importObject.env.ws_open = ws_open; importObject.env.ws_open = ws_open;
importObject.env.ws_revive = ws_revive;
importObject.env.ws_write = ws_write; importObject.env.ws_write = ws_write;
importObject.env.ws_read = ws_read; importObject.env.ws_read = ws_read;
importObject.env.ws_available = ws_available; importObject.env.ws_available = ws_available;

View file

@ -10,7 +10,6 @@ use pc::*;
#[repr(i32)] #[repr(i32)]
pub enum QuadWsState { pub enum QuadWsState {
WsNotExisting = -1,
WsDisconnected = 0, WsDisconnected = 0,
WsConnected = 1, WsConnected = 1,
WsClosed = 2, WsClosed = 2,
@ -21,7 +20,7 @@ pub struct QuadWs {
impl QuadWs { impl QuadWs {
pub fn new(url: String) -> Self { pub fn new(url: String) -> Self {
Self { Self {
channel: ws_open_rust(url).unwrap(), channel: ws_open_rust(url).unwrap()
} }
} }
pub fn write(&mut self, data: Vec<u8>) -> bool { pub fn write(&mut self, data: Vec<u8>) -> bool {
@ -39,6 +38,9 @@ impl QuadWs {
} }
false false
} }
pub fn revive(&mut self){
ws_revive_rust(&mut self.channel);
}
pub fn state(&mut self) -> QuadWsState { pub fn state(&mut self) -> QuadWsState {
let state = ws_state_rust(&mut self.channel); let state = ws_state_rust(&mut self.channel);
if state < 0 || state > 2 { if state < 0 || state > 2 {

View file

@ -3,59 +3,98 @@ use std::net::TcpStream;
use websocket::{native_tls::TlsStream, sync::Client, ClientBuilder, OwnedMessage, WebSocketError}; use websocket::{native_tls::TlsStream, sync::Client, ClientBuilder, OwnedMessage, WebSocketError};
enum WsClient { enum WsClient {
None, Closed,
Disconnected,
Insecure(Client<TcpStream>), Insecure(Client<TcpStream>),
Secure(Client<TlsStream<TcpStream>>), Secure(Client<TlsStream<TcpStream>>),
} }
pub struct WsConnection { pub struct WsConnection {
client: WsClient, client: WsClient,
_url: String, url: String,
} }
pub type WsChannnel = WsConnection; pub type WsChannnel = WsConnection;
pub fn ws_open_rust(url: String) -> Option<WsChannnel> { pub fn ws_open_rust(url: String) -> Option<WsChannnel> {
let secure = url.starts_with("wss"); 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() { if builder.is_err() {
return None; 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 { if secure {
let connector = builder.connect_secure(None); let connector = builder.connect_secure(None);
if connector.is_err() { if connector.is_err() {
return Some(WsConnection { return Some(WsConnection {
client: WsClient::None, client: WsClient::Disconnected,
_url: url, url,
}); });
} }
let client = connector.expect("Failed to expect none err"); let client = connector.expect("Failed to expect none err");
client.set_nonblocking(true).unwrap(); client.set_nonblocking(true).unwrap();
return Some(WsConnection { return Some(WsConnection {
client: WsClient::Secure(client), client: WsClient::Secure(client),
_url: url, url,
}); });
} }
let connector = builder.connect_insecure(); let connector = builder.connect_insecure();
if connector.is_err() { if connector.is_err() {
return Some(WsConnection { return Some(WsConnection {
client: WsClient::None, client: WsClient::Disconnected,
_url: url, url,
}); });
} }
let client = connector.expect("Failed to expect none err"); let client = connector.expect("Failed to expect none err");
client.set_nonblocking(true).unwrap(); client.set_nonblocking(true).unwrap();
return Some(WsConnection { return Some(WsConnection {
client: WsClient::Insecure(client), 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 { pub fn ws_write_raw(socket: &mut WsChannnel, data: OwnedMessage) -> bool {
match &mut socket.client { match &mut socket.client {
WsClient::None => { WsClient::Closed => {
return false;
}
WsClient::Disconnected => {
return false; return false;
} }
WsClient::Insecure(client) => { WsClient::Insecure(client) => {
@ -73,9 +112,10 @@ pub fn ws_write_rust(socket: &mut WsChannnel, data: Vec<u8>) -> bool {
pub fn ws_read_rust(socket: &mut WsChannnel) -> Option<Vec<u8>> { pub fn ws_read_rust(socket: &mut WsChannnel) -> Option<Vec<u8>> {
let message: Result<OwnedMessage, WebSocketError> = match socket.client { let message: Result<OwnedMessage, WebSocketError> = match socket.client {
WsClient::None => Err(WebSocketError::NoDataAvailable), WsClient::Closed => Err(WebSocketError::NoDataAvailable),
WsClient::Insecure(ref mut client) => client.recv_message(), WsClient::Insecure(ref mut client) => client.recv_message(),
WsClient::Secure(ref mut client) => client.recv_message(), WsClient::Secure(ref mut client) => client.recv_message(),
WsClient::Disconnected => Err(WebSocketError::NoDataAvailable),
}; };
match message { match message {
Ok(message) => match message { Ok(message) => match message {
@ -84,7 +124,7 @@ pub fn ws_read_rust(socket: &mut WsChannnel) -> Option<Vec<u8>> {
return Some(data); return Some(data);
} }
websocket::OwnedMessage::Close(_) => { websocket::OwnedMessage::Close(_) => {
socket.client = WsClient::None; socket.client = WsClient::Disconnected;
} }
websocket::OwnedMessage::Ping(ping) => { websocket::OwnedMessage::Ping(ping) => {
let message = OwnedMessage::Pong(ping); let message = OwnedMessage::Pong(ping);
@ -95,7 +135,7 @@ pub fn ws_read_rust(socket: &mut WsChannnel) -> Option<Vec<u8>> {
Err(ref e) => match e { Err(ref e) => match e {
WebSocketError::IoError(err) => if err.kind() == std::io::ErrorKind::WouldBlock {}, WebSocketError::IoError(err) => if err.kind() == std::io::ErrorKind::WouldBlock {},
WebSocketError::NoDataAvailable => { WebSocketError::NoDataAvailable => {
socket.client = WsClient::None; socket.client = WsClient::Disconnected;
} }
_ => {} _ => {}
}, },
@ -105,28 +145,24 @@ pub fn ws_read_rust(socket: &mut WsChannnel) -> Option<Vec<u8>> {
pub fn ws_close_rust(socket: &mut WsChannnel) { pub fn ws_close_rust(socket: &mut WsChannnel) {
match &socket.client { match &socket.client {
WsClient::None => {} WsClient::Closed => {}
WsClient::Insecure(client) => { WsClient::Insecure(client) => {
client.shutdown().unwrap(); client.shutdown().unwrap();
socket.client = WsClient::None; socket.client = WsClient::Closed;
} }
WsClient::Secure(client) => { WsClient::Secure(client) => {
client.shutdown().unwrap(); 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 { match &socket.client {
WsClient::None => { WsClient::Closed => 2,
2 WsClient::Insecure(_) => 1,
} WsClient::Secure(_) => 1,
WsClient::Insecure(_) => { WsClient::Disconnected => 0,
1
}
WsClient::Secure(_) => {
1
}
} }
} }

View file

@ -4,6 +4,7 @@ pub type WsChannnel = i32;
extern "C" { extern "C" {
fn ws_open(ptr: *const i8, len: u32) -> WsChannnel; 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_write(id: WsChannnel, ptr: *const u8, len: u32) -> bool;
fn ws_read(id: WsChannnel, ptr: *const u8, len: u32); fn ws_read(id: WsChannnel, ptr: *const u8, len: u32);
fn ws_available(id: WsChannnel) -> i32; fn ws_available(id: WsChannnel) -> i32;
@ -21,6 +22,10 @@ pub fn ws_open_rust(url: String) -> Option<WsChannnel> {
} }
} }
pub fn ws_revive_rust(socket: &mut WsChannnel) -> bool {
return unsafe { ws_revive(*socket) };
}
pub fn ws_write_rust(socket: &mut WsChannnel, data: Vec<u8>) -> bool { pub fn ws_write_rust(socket: &mut WsChannnel, data: Vec<u8>) -> bool {
let buf = data.as_slice(); let buf = data.as_slice();
let succ = unsafe { ws_write(*socket, buf.as_ptr(), buf.len() as u32) }; 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) }; 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) }; let state = unsafe { ws_state(*socket) };
return state; return state;
} }