pub struct Handle<H>where
H: WebImpl,{ /* private fields */ }web03 only.Expand description
A handle to the WebSocket service.
Implementations§
Source§impl<H> Handle<H>where
H: WebImpl,
impl<H> Handle<H>where
H: WebImpl,
Sourcepub fn format(&self) -> Format
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.
pub fn channel(&self) -> ChannelBuilder<'_, H, EmptyCallback>
Sourcepub fn request(&self) -> RequestBuilder<'_, H, EmptyBody, EmptyCallback>
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>
}
}
}Sourcepub fn on_broadcast<T>(
&self,
callback: impl Callback<Result<Packet<T>, Error>>,
) -> Listenerwhere
T: Broadcast,
pub fn on_broadcast<T>(
&self,
callback: impl Callback<Result<Packet<T>, Error>>,
) -> Listenerwhere
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>
}
}
}Sourcepub fn on_raw_broadcast<T>(
&self,
callback: impl Callback<Result<RawPacket, Error>>,
) -> Listenerwhere
T: Broadcast,
pub fn on_raw_broadcast<T>(
&self,
callback: impl Callback<Result<RawPacket, Error>>,
) -> Listenerwhere
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>
}
}
}Sourcepub fn on_state_change(
&self,
callback: impl Callback<State>,
) -> (State, StateListener)
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> Default for Handle<H>where
H: WebImpl,
Construct a default handle that is not connected to a backend.
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§impl<H> ImplicitClone for Handle<H>where
H: WebImpl,
Available on crate features yew022 or yew023 only.
impl<H> ImplicitClone for Handle<H>where
H: WebImpl,
yew022 or yew023 only.Source§fn implicit_clone(&self) -> Self
fn implicit_clone(&self) -> Self
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§
impl<Token, Builder, How> AllPropsFor<Builder, How> for Tokenwhere
Builder: Buildable<Token>,
<Builder as Buildable<Token>>::WrappedToken: HasAllProps<<Builder as Buildable<Token>>::Output, How>,
impl<Token, Builder, How> AllPropsFor<Builder, How> for Tokenwhere
Builder: Buildable<Token>,
<Builder as Buildable<Token>>::WrappedToken: HasAllProps<<Builder as Buildable<Token>>::Output, How>,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> HasAllProps<(), T> for T
impl<T> HasAllProps<(), T> for T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoPropValue<Option<T>> for T
impl<T> IntoPropValue<Option<T>> for T
Source§fn into_prop_value(self) -> Option<T>
fn into_prop_value(self) -> Option<T>
self to a value of a Properties struct.Source§impl<T> IntoPropValue<Option<T>> for T
impl<T> IntoPropValue<Option<T>> for T
Source§fn into_prop_value(self) -> Option<T>
fn into_prop_value(self) -> Option<T>
self to a value of a Properties struct.Source§impl<T> IntoPropValue<T> for T
impl<T> IntoPropValue<T> for T
Source§fn into_prop_value(self) -> T
fn into_prop_value(self) -> T
self to a value of a Properties struct.Source§impl<T> IntoPropValue<T> for T
impl<T> IntoPropValue<T> for T
Source§fn into_prop_value(self) -> T
fn into_prop_value(self) -> T
self to a value of a Properties struct.