Websockets binary msgs (#2109)

* info how to run webserver with non-EOL python3

* example how to send and receive binary messages over websockets
This commit is contained in:
Michael Kefeder 2020-04-28 20:16:54 +02:00 committed by GitHub
parent 8728f40aac
commit a521c9012c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 8 deletions

View File

@ -9,11 +9,16 @@ crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = "0.2.60"
js-sys = "0.3"
[dependencies.web-sys]
version = "0.3.22"
features = [
"BinaryType",
"Blob",
"ErrorEvent",
"FileReader",
"MessageEvent",
"ProgressEvent",
"WebSocket",
]

View File

@ -19,5 +19,6 @@ Then serve the statics and navigate to `host:port`
http
# or use python
python -m SimpleHTTPServer
python2 -m SimpleHTTPServer
python3 -m http.server
```

View File

@ -16,15 +16,45 @@ extern "C" {
pub fn start_websocket() -> Result<(), JsValue> {
// Connect to an echo server
let ws = WebSocket::new("wss://echo.websocket.org")?;
// For small binary messages, like CBOR, Arraybuffer is more efficient than Blob handling
ws.set_binary_type(web_sys::BinaryType::Arraybuffer);
// create callback
let cloned_ws = ws.clone();
let onmessage_callback = Closure::wrap(Box::new(move |e: MessageEvent| {
// handle message
let response = e
.data()
.as_string()
.expect("Can't convert received data to a string");
console_log!("message event, received data: {:?}", response);
// Handle difference Text/Binary,...
if let Ok(abuf) = e.data().dyn_into::<js_sys::ArrayBuffer>() {
console_log!("message event, received arraybuffer: {:?}", abuf);
let array = js_sys::Uint8Array::new(&abuf);
let len = array.byte_length() as usize;
console_log!("Arraybuffer received {}bytes: {:?}", len, array.to_vec());
// here you can for example use Serde Deserialize decode the message
// for demo purposes we switch back to Blob-type and send off another binary message
cloned_ws.set_binary_type(web_sys::BinaryType::Blob);
match cloned_ws.send_with_u8_array(&vec![5, 6, 7, 8]) {
Ok(_) => console_log!("binary message successfully sent"),
Err(err) => console_log!("error sending message: {:?}", err),
}
} else if let Ok(blob) = e.data().dyn_into::<web_sys::Blob>() {
console_log!("message event, received blob: {:?}", blob);
// better alternative to juggling with FileReader is to use https://crates.io/crates/gloo-file
let fr = web_sys::FileReader::new().unwrap();
let fr_c = fr.clone();
// create onLoadEnd callback
let onloadend_cb = Closure::wrap(Box::new(move |_e: web_sys::ProgressEvent| {
let array = js_sys::Uint8Array::new(&fr_c.result().unwrap());
let len = array.byte_length() as usize;
console_log!("Blob received {}bytes: {:?}", len, array.to_vec());
// here you can for example use the received image/png data
})
as Box<dyn FnMut(web_sys::ProgressEvent)>);
fr.set_onloadend(Some(onloadend_cb.as_ref().unchecked_ref()));
fr.read_as_array_buffer(&blob).expect("blob not readable");
onloadend_cb.forget();
} else if let Ok(txt) = e.data().dyn_into::<js_sys::JsString>() {
console_log!("message event, received Text: {:?}", txt);
} else {
console_log!("message event, received Unknown: {:?}", e.data());
}
}) as Box<dyn FnMut(MessageEvent)>);
// set message event handler on WebSocket
ws.set_onmessage(Some(onmessage_callback.as_ref().unchecked_ref()));
@ -44,6 +74,11 @@ pub fn start_websocket() -> Result<(), JsValue> {
Ok(_) => console_log!("message successfully sent"),
Err(err) => console_log!("error sending message: {:?}", err),
}
// send off binary message
match cloned_ws.send_with_u8_array(&vec![0, 1, 2, 3]) {
Ok(_) => console_log!("binary message successfully sent"),
Err(err) => console_log!("error sending message: {:?}", err),
}
}) as Box<dyn FnMut(JsValue)>);
ws.set_onopen(Some(onopen_callback.as_ref().unchecked_ref()));
onopen_callback.forget();