workers-rs icon indicating copy to clipboard operation
workers-rs copied to clipboard

Implement Hibernatable Web Sockets API

Open DylanRJohnston opened this issue 1 year ago • 4 comments

Hey all, this contains my attempt at writing the bindings for the Hibernating Web Sockets API. I haven't implemented the setWebSocketAutoResponse suite of functions yet as I don't have immediate use for them and I'd like feedback on the implementation so far.

Supersedes #434 as I was unable to change the branch for the pull request and it contained more changes than just the Hibernatable web sockets API.

DylanRJohnston avatar Jan 17 '24 03:01 DylanRJohnston

I did a quick functional test of this branch and it works in my project-- I am testing 2 websockets in a durable object, using binary messages and hibernation.

eric-seppanen avatar Jan 17 '24 19:01 eric-seppanen

Hey @DylanRJohnston, I commented on the previous PR about state.getTags(ws). You previously asked which version of wrangler supported it and I believe it should be [email protected].

MellowYarker avatar Feb 06 '24 22:02 MellowYarker

As an experiment I added getTags support to my local branch, and the following works for me:

impl State {
    /// Retrieve tags from a hibernatable websocket
    pub fn get_tags(&self, websocket: &WebSocket) -> Vec<String> {
        let tags = self.inner.get_tags(websocket.as_ref());
        let tags: js_sys::Array = tags.dyn_into().expect("get_tags returned wrong type");

        tags.iter()
            .map(|tag| tag.as_string().expect("get_tags returned non-string value"))
            .collect()
    }
}

And some wasm_bindgen glue in worker-sys state.rs:

#[wasm_bindgen(method, js_name=getTags)]
pub fn get_tags(this: &DurableObjectState, ws: &web_sys::WebSocket) -> wasm_bindgen::JsValue;

Maybe the error handling is unnecessary? Probably unchecked_into would be fine; not sure if there's an unchecked way to do as_string.

eric-seppanen avatar Feb 06 '24 22:02 eric-seppanen

I think you can change the signature of

pub fn get_tags(this: &DurableObjectState, ws: &web_sys::WebSocket) -> wasm_bindgen::JsValue;

into

pub fn get_tags(this: &DurableObjectState, ws: &web_sys::WebSocket) -> Vec<String>

and have wasm_bindgen do the work of converting it for you.

DylanRJohnston avatar Feb 07 '24 08:02 DylanRJohnston

Nice work & a big thanks for putting this together. I was able to switch over to use the Hibernatable Web Sockets API fairly easily with this patch!

j-white avatar Feb 26 '24 17:02 j-white