Wasm-bindgen: Get Transferable in Rust

Created on 7 May 2019  路  3Comments  路  Source: rustwasm/wasm-bindgen

Hi (again),

Following my work, I start a worker and I send a message to it (to an image decoder).
After the decoding I wanna to get back on the Rust object so I plan to use the onmessage method.

I cannot arrive to get back the data ArrayBuffer as I need to send it with postMessage including a transferable object.

Do you know if we can get back the ArrayBuffer in Rust ?

Thanks,
Marc-Antoine

question

Most helpful comment

@alexcrichton Actually, transferrable objects don't have anything to do with SharedArrayBuffer.

They're a special kind of object which can be sent between Workers without a copy.

Right now that means ArrayBuffer, MessagePort, ImageBitmap, and OffscreenCanvas (but more types might become transferrable in the future).


@MarcAntoine-Arnaud You would use the post_message_with_transfer method, like this:

let worker = ...;
let array_buffer = ...;

worker.post_message_with_transfer(&array_buffer, &Array::of1(&array_buffer)).unwrap_throw();

Then to receive it back from the Worker, you would do something like this:

let cb = Closure::wrap(Box::new(|event| {
    let array_buffer: ArrayBuffer = event.data().dyn_into().unwrap_throw();

    // Use ArrayBuffer...
}) as Box<FnMut(MessageEvent)>);

worker.set_onmessage(Some(cb.as_ref().unchecked_ref()));

All 3 comments

Thanks for the report! Until SharedArrayBuffer is stable the only way to transfer data between workers on the web is to do full copies which means you can't send a Rust struct from one thread to another with workers. For that you may want to use JSON and/or the serde support!

@alexcrichton Actually, transferrable objects don't have anything to do with SharedArrayBuffer.

They're a special kind of object which can be sent between Workers without a copy.

Right now that means ArrayBuffer, MessagePort, ImageBitmap, and OffscreenCanvas (but more types might become transferrable in the future).


@MarcAntoine-Arnaud You would use the post_message_with_transfer method, like this:

let worker = ...;
let array_buffer = ...;

worker.post_message_with_transfer(&array_buffer, &Array::of1(&array_buffer)).unwrap_throw();

Then to receive it back from the Worker, you would do something like this:

let cb = Closure::wrap(Box::new(|event| {
    let array_buffer: ArrayBuffer = event.data().dyn_into().unwrap_throw();

    // Use ArrayBuffer...
}) as Box<FnMut(MessageEvent)>);

worker.set_onmessage(Some(cb.as_ref().unchecked_ref()));

I have tested it and it works like that:

// Worker in JS
postMessage(output.buffer, [output.buffer])

then I can get back the ArrayBuffer in Rust as @Pauan mentioned.

My initial wish is to send also informations about decoded frame, so I wanna to send:

// Worker in JS
postMessage({
  'frame_index': 666,
  'width': 1920,
  'height': 1080,
  'data': output.buffer
}, [output.buffer])

When I receive this message in javascript it works, I can access to all informations.

For Rust I have only access to a JsValue like:
JsValue(Object({"frame_index":666,"width":1920,"height":1088,"data":{}}))
The data seems an empty array...
Do you know how to get back information for that ?
Or if it's not supported right now with wasm-bindgen ?

Marc-Antoine

Was this page helpful?
0 / 5 - 0 ratings

Related issues

aschampion picture aschampion  路  4Comments

poccariswet picture poccariswet  路  3Comments

bantic picture bantic  路  4Comments

hunterlester picture hunterlester  路  4Comments

shepmaster picture shepmaster  路  3Comments