pub struct Message { /* private fields */ }
Expand description

A WebSocket message.

This will likely become a non-exhaustive enum in the future, once that language feature has stabilized.

Implementations

Construct a new Text Message.

Examples found in repository?
src/test.rs (line 571)
570
571
572
    pub async fn send_text(&mut self, text: impl Into<String>) {
        self.send(crate::ws::Message::text(text)).await;
    }
More examples
Hide additional examples
examples/websockets_chat.rs (line 110)
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
async fn user_message(my_id: usize, msg: Message, users: &Users) {
    // Skip any non-Text messages...
    let msg = if let Ok(s) = msg.to_str() {
        s
    } else {
        return;
    };

    let new_msg = format!("<User#{}>: {}", my_id, msg);

    // New message from this user, send it to everyone else (except same uid)...
    for (&uid, tx) in users.read().await.iter() {
        if my_id != uid {
            if let Err(_disconnected) = tx.send(Ok(Message::text(new_msg.clone()))) {
                // The tx is disconnected, our `user_disconnected` code
                // should be happening in another task, nothing more to
                // do here.
            }
        }
    }
}

Construct a new Binary Message.

Construct a new Ping Message.

Construct a new Pong Message.

Note that one rarely needs to manually construct a Pong message because the underlying tungstenite socket automatically responds to the Ping messages it receives. Manual construction might still be useful in some cases like in tests or to send unidirectional heartbeats.

Construct the default Close Message.

Construct a Close Message with a code and reason.

Returns true if this message is a Text message.

Returns true if this message is a Binary message.

Returns true if this message a is a Close message.

Examples found in repository?
src/test.rs (line 546)
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
    pub async fn handshake<F>(self, f: F) -> Result<WsClient, WsError>
    where
        F: Filter + Clone + Send + Sync + 'static,
        F::Extract: Reply + Send,
        F::Error: IsReject + Send,
    {
        let (upgraded_tx, upgraded_rx) = oneshot::channel();
        let (wr_tx, wr_rx) = mpsc::unbounded_channel();
        let wr_rx = UnboundedReceiverStream::new(wr_rx);
        let (rd_tx, rd_rx) = mpsc::unbounded_channel();

        tokio::spawn(async move {
            use tokio_tungstenite::tungstenite::protocol;

            let (addr, srv) = crate::serve(f).bind_ephemeral(([127, 0, 0, 1], 0));

            let mut req = self
                .req
                .header("connection", "upgrade")
                .header("upgrade", "websocket")
                .header("sec-websocket-version", "13")
                .header("sec-websocket-key", "dGhlIHNhbXBsZSBub25jZQ==")
                .req;

            let query_string = match req.uri().query() {
                Some(q) => format!("?{}", q),
                None => String::from(""),
            };

            let uri = format!("http://{}{}{}", addr, req.uri().path(), query_string)
                .parse()
                .expect("addr + path is valid URI");

            *req.uri_mut() = uri;

            // let mut rt = current_thread::Runtime::new().unwrap();
            tokio::spawn(srv);

            let upgrade = ::hyper::Client::builder()
                .build(AddrConnect(addr))
                .request(req)
                .and_then(|res| hyper::upgrade::on(res));

            let upgraded = match upgrade.await {
                Ok(up) => {
                    let _ = upgraded_tx.send(Ok(()));
                    up
                }
                Err(err) => {
                    let _ = upgraded_tx.send(Err(err));
                    return;
                }
            };
            let ws = crate::ws::WebSocket::from_raw_socket(
                upgraded,
                protocol::Role::Client,
                Default::default(),
            )
            .await;

            let (tx, rx) = ws.split();
            let write = wr_rx.map(Ok).forward(tx).map(|_| ());

            let read = rx
                .take_while(|result| match result {
                    Err(_) => future::ready(false),
                    Ok(m) => future::ready(!m.is_close()),
                })
                .for_each(move |item| {
                    rd_tx.send(item).expect("ws receive error");
                    future::ready(())
                });

            future::join(write, read).await;
        });

        match upgraded_rx.await {
            Ok(Ok(())) => Ok(WsClient {
                tx: wr_tx,
                rx: rd_rx,
            }),
            Ok(Err(err)) => Err(WsError::new(err)),
            Err(_canceled) => panic!("websocket handshake thread panicked"),
        }
    }

Returns true if this message is a Ping message.

Returns true if this message is a Pong message.

Try to get the close frame (close code and reason)

Try to get a reference to the string text, if this is a Text message.

Examples found in repository?
examples/websockets_chat.rs (line 99)
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
async fn user_message(my_id: usize, msg: Message, users: &Users) {
    // Skip any non-Text messages...
    let msg = if let Ok(s) = msg.to_str() {
        s
    } else {
        return;
    };

    let new_msg = format!("<User#{}>: {}", my_id, msg);

    // New message from this user, send it to everyone else (except same uid)...
    for (&uid, tx) in users.read().await.iter() {
        if my_id != uid {
            if let Err(_disconnected) = tx.send(Ok(Message::text(new_msg.clone()))) {
                // The tx is disconnected, our `user_disconnected` code
                // should be happening in another task, nothing more to
                // do here.
            }
        }
    }
}

Return the bytes of this message, if the message can contain data.

Destructure this message into binary data.

Examples found in repository?
src/filters/ws.rs (line 389)
388
389
390
    fn into(self) -> Vec<u8> {
        self.into_bytes()
    }

Trait Implementations

Returns a copy of the value. Read more

Performs copy-assignment from source. Read more

Formats the value using the given formatter. Read more

Performs the conversion.

This method tests for self and other values to be equal, and is used by ==. Read more

This method tests for !=.

The type of value produced by the sink when an error occurs.

Attempts to prepare the Sink to receive a value. Read more

Begin the process of sending a value to the sink. Each call to this function must be preceded by a successful call to poll_ready which returned Poll::Ready(Ok(())). Read more

Flush any remaining output from this sink. Read more

Flush any remaining output and close this sink, if necessary. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Compare self to key and return true if they are equal.

Performs the conversion.

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

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

Performs the conversion.

Should always be Self

The resulting type after obtaining ownership.

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

🔬 This is a nightly-only experimental API. (toowned_clone_into)

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

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.