logo
pub struct Event { /* private fields */ }
Expand description

A Server-Sent Event (SSE) in a Server-Sent EventStream.

A server-sent event is either a field or a comment. Comments can be constructed via Event::comment() while fields can be constructed via Event::data(), Event::json(), and Event::retry().

use rocket::tokio::time::Duration;
use rocket::response::stream::Event;

// A `data` event with message "Hello, SSE!".
let event = Event::data("Hello, SSE!");

// The same event but with event name of `hello`.
let event = Event::data("Hello, SSE!").event("hello");

// A `retry` event to set the client-side reconnection time.
let event = Event::retry(Duration::from_secs(5));

// An event with an attached comment, event name, and ID.
let event = Event::data("Hello, SSE!")
    .with_comment("just a hello message")
    .event("hello")
    .id("1");

We largely defer to MDN’s using server-sent events documentation for client-side details but reproduce, in our words, relevant server-side documentation here.

Pitfalls

Server-Sent Events suffer from certain pitfalls. We encourage readers to read through pitfalls before making use of Rocket’s SSE support.

Comments

A server-sent comment, created via Event::comment(), is an event that appears only in the raw server-sent event data stream and is inaccessible by most clients. This includes JavaScript’s EventSource. As such, they serve little utility beyond debugging a raw data stream and keeping a connection alive. See hearbeat for information on Rocket’s EventStream keep-alive.

Fields

A server-sent field can be one of four kinds:

  • retry

    A retry event, created via Event::retry(), sets the reconnection time on the client side. It is the duration the client will wait before attempting to reconnect when a connection is lost. Most applications will not need to set a retry, opting instead to use the implementation’s default or to reconnect manually on error.

  • id

    Sets the event id to associate all subsequent fields with. This value cannot be retrieved directly via most clients, including JavaScript EventSource. Instead, it is sent by the implementation on reconnection via the Last-Event-ID header. An id can be attached to other fields via the Event::id() builder method.

  • event

    Sets the event name to associate the next data field with. In JavaScript’s EventSource, this is the event to be listened for, which defaults to message. An event can be attached to other fields via the Event::event() builder method.

  • data

    Sends data to dispatch as an event at the client. In JavaScript’s EventSource, this (and only this) results in an event handler for event, specified just prior, being triggered. A data field can be created via the Event::data() or Event::json() constructors.

Implementation Notes

A constructed Event always emits its fields in the following order:

  1. comment
  2. retry
  3. id
  4. event
  5. data

The event and id fields cannot contain new lines or carriage returns. Rocket’s default implementation automatically converts new lines and carriage returns in event and id fields to spaces.

The data and comment fields cannot contain carriage returns. Rocket converts the unencoded sequence \r\n and the isolated \r into a protocol-level \n, that is, in such a way that they are interpreted as \n at the client. For example, the raw message foo\r\nbar\rbaz is received as foo\nbar\nbaz at the client-side. Encoded sequences, such as those emitted by Event::json(), have no such restrictions.

Implementations

Creates a new Event with an empty data field.

This is exactly equivalent to Event::data("").

Example
use rocket::response::stream::Event;

let event = Event::empty();
Available on crate feature json only.

Creates a new Event with a data field of data serialized as JSON.

Example
use rocket::serde::Serialize;
use rocket::response::stream::Event;

#[derive(Serialize)]
#[serde(crate = "rocket::serde")]
struct MyData<'r> {
    string: &'r str,
    number: usize,
}

let data = MyData { string: "hello!", number: 10 };
let event = Event::json(&data);

Creates a new Event with a data field containing the raw data.

Raw SSE is Lossy

Unencoded carriage returns cannot be expressed in the protocol. Thus, any carriage returns in data will not appear at the client-side. Instead, the sequence \r\n and the isolated \r will each appear as \n at the client-side. For example, the message foo\r\nbar\rbaz is received as foo\nbar\nbaz at the client-side.

See pitfalls for more details.

Example
use rocket::response::stream::Event;

// A `data` event with message "Hello, SSE!".
let event = Event::data("Hello, SSE!");

Creates a new comment Event.

As with Event::data(), unencoded carriage returns cannot be expressed in the protocol. Thus, any carriage returns in data will not appear at the client-side. For comments, this is generally not a concern as comments are discarded by client-side libraries.

Example
use rocket::response::stream::Event;

let event = Event::comment("bet you'll never see me!");

Creates a new retry Event.

Example
use rocket::response::stream::Event;
use rocket::tokio::time::Duration;

let event = Event::retry(Duration::from_millis(250));

Sets the value of the ‘event’ (event type) field.

Event names may not contain new lines \n or carriage returns \r. If event does contain new lines or carriage returns, they are replaced with spaces ( ) before being sent to the client.

Example
use rocket::response::stream::Event;

// The event name is "start".
let event = Event::data("hi").event("start");

// The event name is "then end", with `\n` replaced with ` `.
let event = Event::data("bye").event("then\nend");

Sets the value of the ‘id’ (last event ID) field.

Event IDs may not contain new lines \n or carriage returns \r. If id does contain new lines or carriage returns, they are replaced with spaces ( ) before being sent to the client.

Example
use rocket::response::stream::Event;

// The event ID is "start".
let event = Event::data("hi").id("start");

// The event ID is "then end", with `\n` replaced with ` `.
let event = Event::data("bye").id("then\nend");

Sets the value of the ‘id’ field. It may not contain newlines.

Sets or replaces the value of the data field.

Example
use rocket::response::stream::Event;

// The data "hello" will be sent.
let event = Event::data("hi").with_data("hello");

// The two below are equivalent.
let event = Event::comment("bye").with_data("goodbye");
let event = Event::data("goodbyte").with_comment("bye");

Sets or replaces the value of the comment field.

Example
use rocket::response::stream::Event;

// The comment "🚀" will be sent.
let event = Event::comment("Rocket is great!").with_comment("🚀");

// The two below are equivalent.
let event = Event::comment("bye").with_data("goodbye");
let event = Event::data("goodbyte").with_comment("bye");

Sets or replaces the value of the retry field.

Example
use rocket::response::stream::Event;
use rocket::tokio::time::Duration;

// The reconnection will be set to 10 seconds.
let event = Event::retry(Duration::from_millis(500))
    .with_retry(Duration::from_secs(10));

// The two below are equivalent.
let event = Event::comment("bye").with_retry(Duration::from_millis(500));
let event = Event::retry(Duration::from_millis(500)).with_comment("bye");

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

Feeds this value into the given Hasher. Read more

Feeds a slice of this type into the given Hasher. Read more

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

This method tests for !=.

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.

Returns the argument unchanged.

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

Calls U::from(self).

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

Converts self into a collection.

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.

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

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