Skip to main content

Handle

Struct Handle 

Source
pub struct Handle<H>
where H: WebImpl,
{ /* private fields */ }
Available on crate feature web03 only.
Expand description

A handle to the WebSocket service.

Implementations§

Source§

impl<H> Handle<H>
where H: WebImpl,

Source

pub fn format(&self) -> Format

Open a new logical channel to the WebSocket server.

A channel can be uniquely identified on the client and server side over a single connection. This means that if you send a request over a channel using Channel::request, the server can access the ChannelId to determine which channel sent the request and the client has the ability to correlate any responses sent by the server by inspecting Packet::channel or RawPacket::channel.

The ChannelId can also be sent out-of-bounds, for example as part of the body of a ws::Server::broadcast allowing the client to filter broadcasts that originated from itself to avoid bouncing updates.

The maximum number of channels is implementation defined, but expect it to be relatively low like 65535 (non-zero 16 bits) to reduce payload sizes. Failure to allocate a channel is an error.

§Examples
use yew::prelude::*;
use musli_web::web03::prelude::*;

enum Msg {
    OnChannel(Result<ws::Channel, ws::Error>),
}

#[derive(Properties, PartialEq)]
struct Props {
    ws: ws::Handle,
}

struct App {
    _channel_open: ws::Request,
    channel: ws::Channel,
}

impl Component for App {
    type Message = Msg;
    type Properties = Props;

    fn create(ctx: &Context<Self>) -> Self {
        let link = ctx.link().clone();

        let _channel_open = ctx.props().ws
            .channel()
            .on_open(ctx.link().callback(Msg::OnChannel))
            .send();

        Self {
            _channel_open: _channel_open,
            channel: ws::Channel::default(),
        }
    }

    fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
        match msg {
            Msg::OnChannel(result) => {
                if let Ok(channel) = result {
                    self.channel = channel;
                }

                true
            }
        }
    }

    fn view(&self, ctx: &Context<Self>) -> Html {
        html! {
            <div>
                <h1>{"WebSocket Example"}</h1>
            </div>
        }
    }
}

The Format currently in effect for message bodies.

Before the connection has been opened this is the format which was requested through ServiceBuilder::format. Once the connection is open it is the format the server actually agreed to, which can differ if the server does not support what was asked for.

Source

pub fn channel(&self) -> ChannelBuilder<'_, H, EmptyCallback>

Source

pub fn request(&self) -> RequestBuilder<'_, H, EmptyBody, EmptyCallback>

Send a request of type T.

Returns a handle for the request.

If the handle is dropped, the request is cancelled.

§Examples
use yew::prelude::*;
use musli_web::web03::prelude::*;

mod api {
    use musli::{Decode, Encode};
    use musli_web::api;

    #[derive(Encode, Decode)]
    pub struct HelloRequest<'de> {
        pub message: &'de str,
    }

    #[derive(Encode, Decode)]
    pub struct HelloResponse<'de> {
        pub message: &'de str,
    }

    api::define! {
        pub type Hello;

        impl Endpoint for Hello {
            impl<'de> Request for HelloRequest<'de>;
            type Response<'de> = HelloResponse<'de>;
        }
    }
}

enum Msg {
    OnHello(Result<ws::Packet<api::Hello>, ws::Error>),
}

#[derive(Properties, PartialEq)]
struct Props {
    ws: ws::Handle,
}

struct App {
    message: String,
    _hello: ws::Request,
}

impl Component for App {
    type Message = Msg;
    type Properties = Props;

    fn create(ctx: &Context<Self>) -> Self {
        let hello = ctx.props().ws
            .request()
            .body(api::HelloRequest { message: "Hello!"})
            .on_packet(ctx.link().callback(Msg::OnHello))
            .send();

        Self {
            message: String::from("No Message :("),
            _hello: hello,
        }
    }

    fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
        match msg {
            Msg::OnHello(Err(error)) => {
                tracing::error!("Request error: {:?}", error);
                false
            }
            Msg::OnHello(Ok(packet)) => {
                if let Ok(response) = packet.decode() {
                    self.message = response.message.to_owned();
                }

                true
            }
        }
    }

    fn view(&self, ctx: &Context<Self>) -> Html {
        html! {
            <div>
                <h1>{"WebSocket Example"}</h1>
                <p>{format!("Message: {}", self.message)}</p>
            </div>
        }
    }
}
Source

pub fn on_broadcast<T>( &self, callback: impl Callback<Result<Packet<T>, Error>>, ) -> Listener
where T: Broadcast,

Listen for broadcasts of type T.

Returns a handle for the listener that will cancel the listener if dropped.

§Examples
use yew::prelude::*;
use musli_web::web03::prelude::*;

mod api {
    use musli::{Decode, Encode};
    use musli_web::api;

    #[derive(Encode, Decode)]
    pub struct TickEvent<'de> {
        pub message: &'de str,
        pub tick: u32,
    }

    api::define! {
        pub type Tick;

        impl Broadcast for Tick {
            impl<'de> Event for TickEvent<'de>;
        }
    }
}

enum Msg {
    Tick(Result<ws::Packet<api::Tick>, ws::Error>),
}

#[derive(Properties, PartialEq)]
struct Props {
    ws: ws::Handle,
}

struct App {
    tick: u32,
    _listen: ws::Listener,
}

impl Component for App {
    type Message = Msg;
    type Properties = Props;

    fn create(ctx: &Context<Self>) -> Self {
        let listen = ctx.props().ws.on_broadcast(ctx.link().callback(Msg::Tick));

        Self {
            tick: 0,
            _listen: listen,
        }
    }

    fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
        match msg {
            Msg::Tick(Err(error)) => {
                tracing::error!("Tick error: {error}");
                false
            }
            Msg::Tick(Ok(packet)) => {
                if let Ok(tick) = packet.decode_event() {
                    self.tick = tick.tick;
                }

                true
            }
        }
    }

    fn view(&self, ctx: &Context<Self>) -> Html {
        html! {
            <div>
                <h1>{"WebSocket Example"}</h1>
                <p>{format!("Tick: {}", self.tick)}</p>
            </div>
        }
    }
}
Source

pub fn on_raw_broadcast<T>( &self, callback: impl Callback<Result<RawPacket, Error>>, ) -> Listener
where T: Broadcast,

Listen for broadcasts of type T.

Returns a handle for the listener that will cancel the listener if dropped.

§Examples
use yew::prelude::*;
use musli_web::web03::prelude::*;

mod api {
    use musli::{Decode, Encode};
    use musli_web::api;

    #[derive(Encode, Decode)]
    pub struct TickEvent<'de> {
        pub message: &'de str,
        pub tick: u32,
    }

    api::define! {
        pub type Tick;

        impl Broadcast for Tick {
            impl<'de> Event for TickEvent<'de>;
        }
    }
}

enum Msg {
    Tick(Result<ws::RawPacket, ws::Error>),
}

#[derive(Properties, PartialEq)]
struct Props {
    ws: ws::Handle,
}

struct App {
    tick: u32,
    _listen: ws::Listener,
}

impl Component for App {
    type Message = Msg;
    type Properties = Props;

    fn create(ctx: &Context<Self>) -> Self {
        let link = ctx.link().clone();
        let listen = ctx.props().ws.on_raw_broadcast::<api::Tick>(ctx.link().callback(Msg::Tick));

        Self {
            tick: 0,
            _listen: listen,
        }
    }

    fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
        match msg {
            Msg::Tick(Err(error)) => {
                tracing::error!("Tick error: {error}");
                false
            }
            Msg::Tick(Ok(packet)) => {
                if let Ok(tick) = packet.decode::<api::TickEvent>() {
                    self.tick = tick.tick;
                }

                true
            }
        }
    }

    fn view(&self, ctx: &Context<Self>) -> Html {
        html! {
            <div>
                <h1>{"WebSocket Example"}</h1>
                <p>{format!("Tick: {}", self.tick)}</p>
            </div>
        }
    }
}
Source

pub fn on_state_change( &self, callback: impl Callback<State>, ) -> (State, StateListener)

Listen for state changes to the underlying connection.

This indicates when the connection is open and ready to receive requests through State::Open, or if it’s closed and requests will be queued through State::Closed.

Note that if you are connecting through a proxy the reported updates might be volatile. It is always best to send a message over the connection on the server side that once received allows the client to know that it is connected.

Dropping the returned handle will cancel the listener.

§Examples
use yew::prelude::*;
use musli_web::web03::prelude::*;

enum Msg {
    StateChange(ws::State),
}

#[derive(Properties, PartialEq)]
struct Props {
    ws: ws::Handle,
}

struct App {
    state: ws::State,
    _listen: ws::StateListener,
}

impl Component for App {
    type Message = Msg;
    type Properties = Props;

    fn create(ctx: &Context<Self>) -> Self {
        let link = ctx.link().clone();

        let (state, listen) = ctx.props().ws.on_state_change(move |state| {
            link.send_message(Msg::StateChange(state));
        });

        Self {
            state,
            _listen: listen,
        }
    }

    fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
        match msg {
            Msg::StateChange(state) => {
                self.state = state;
                true
            }
        }
    }

    fn view(&self, ctx: &Context<Self>) -> Html {
        html! {
            <div>
                <h1>{"WebSocket Example"}</h1>
                <p>{format!("State: {:?}", self.state)}</p>
            </div>
        }
    }
}

Trait Implementations§

Source§

impl<H> Clone for Handle<H>
where H: WebImpl,

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<H> Debug for Handle<H>
where H: WebImpl,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<H> Default for Handle<H>
where H: WebImpl,

Construct a default handle that is not connected to a backend.

§Examples

use musli_web::web03::prelude::*;

let handle = ws::Handle::default();
Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<H> ImplicitClone for Handle<H>
where H: WebImpl,

Available on crate features yew022 or yew023 only.
Source§

fn implicit_clone(&self) -> Self

This function is not magic; it is literally defined as Read more
Source§

impl<H> PartialEq for Handle<H>
where H: WebImpl,

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more

Auto Trait Implementations§

§

impl<H> !RefUnwindSafe for Handle<H>

§

impl<H> !Send for Handle<H>

§

impl<H> !Sync for Handle<H>

§

impl<H> !UnwindSafe for Handle<H>

§

impl<H> Freeze for Handle<H>

§

impl<H> Unpin for Handle<H>

§

impl<H> UnsafeUnpin for Handle<H>

Blanket Implementations§

Source§

impl<Token, Builder, How> AllPropsFor<Builder, How> for Token
where Builder: Buildable<Token>, <Builder as Buildable<Token>>::WrappedToken: HasAllProps<<Builder as Buildable<Token>>::Output, How>,

Source§

impl<Token, Builder, How> AllPropsFor<Builder, How> for Token
where Builder: Buildable<Token>, <Builder as Buildable<Token>>::WrappedToken: HasAllProps<<Builder as Buildable<Token>>::Output, How>,

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> HasAllProps<(), T> for T

Source§

impl<T> HasAllProps<(), T> for T

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoPropValue<Option<T>> for T

Source§

fn into_prop_value(self) -> Option<T>

Convert self to a value of a Properties struct.
Source§

impl<T> IntoPropValue<Option<T>> for T

Source§

fn into_prop_value(self) -> Option<T>

Convert self to a value of a Properties struct.
Source§

impl<T> IntoPropValue<T> for T

Source§

fn into_prop_value(self) -> T

Convert self to a value of a Properties struct.
Source§

impl<T> IntoPropValue<T> for T

Source§

fn into_prop_value(self) -> T

Convert self to a value of a Properties struct.
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<S, T> Upcast<T> for S
where T: UpcastFrom<S> + ?Sized, S: ?Sized,

Source§

fn upcast(&self) -> &T
where Self: ErasableGeneric, T: Sized + ErasableGeneric<Repr = Self::Repr>,

Perform a zero-cost type-safe upcast to a wider ref type within the Wasm bindgen generics type system. Read more
Source§

fn upcast_into(self) -> T
where Self: Sized + ErasableGeneric, T: Sized + ErasableGeneric<Repr = Self::Repr>,

Perform a zero-cost type-safe upcast to a wider type within the Wasm bindgen generics type system. Read more
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more