Crate trillium_channels
source ·Expand description
An implementation of phoenix channels for trillium.rs
Channels are a means of distributing events in soft-realtime to connected websocket clients, including topic-subscription-based fanout.
From the phoenix docs,
Some possible use cases include:
- Chat rooms and APIs for messaging apps
- Breaking news, like “a goal was scored” or “an earthquake is coming”
- Tracking trains, trucks, or race participants on a map
- Events in multiplayer games
- Monitoring sensors and controlling lights
- Notifying a browser that a page’s CSS or JavaScript has changed (this is handy in development)
- Conceptually, Channels are pretty simple.
First, clients connect to the server using WebSockets. Once connected, they join one or more topics. For example, to interact with a public chat room clients may join a topic called public_chat, and to receive updates from a product with ID 7, they may need to join a topic called product_updates:7.
Clients can push messages to the topics they’ve joined, and can also receive messages from them. The other way around, Channel servers receive messages from their connected clients, and can push messages to them too.
Current known differences from phoenix channels:
No long-polling support
Phoenix channels support long polling transports as well as websockets. As most modern browsers and http clients support websockets, as of the current version, trillium channels exclusively are built on them. The design should be flexible to support long polling if it is eventually needed.
No multi-server synchronization yet
Phoenix channels support running several server nodes and distributing
all broadcast messages between them. This will be straightforward to
add to trillium channels in a future revision, but the current
implementation does not synchronize messages across servers. However,
in the mean time, you can use Channel::broadcaster
to return a
ChannelBroadcaster
that can be used to publish and subscribe to
messages between servers using whatever distribution mechanism is
appropriate for your application and deployment. Open a discussion on
the trillium repo for ideas on how this might work for you.
Event routing is handled in user code
Phoenix channels has a notion of registering channel handlers for
different topics, so an implementation might involve registering a
RoomChannel for rooms:*
. Trillium channels does not currently
provide this routing/matching behavior, but will likely do so
eventually.
Simple Example: Chat App
use trillium_channels::{channel, ChannelConn, ChannelEvent, ChannelHandler};
struct ChatChannel;
#[trillium::async_trait]
impl ChannelHandler for ChatChannel {
async fn join_channel(&self, conn: ChannelConn<'_>, event: ChannelEvent) {
match event.topic() {
"rooms:lobby" => {
conn.allow_join(&event, &()).await;
conn.broadcast(("rooms:lobby", "user:entered"));
}
_ => {}
}
}
async fn incoming_message(&self, conn: ChannelConn<'_>, event: ChannelEvent) {
match (event.topic(), event.event()) {
("rooms:lobby", "new:msg") => conn.broadcast(event),
_ => {}
}
}
}
// fn main() {
// trillium_smol::run(channel(ChatChannel));
// }
See channels/examples/channels.rs for a fully functional example that uses the front-end from the phoenix chat example.
Macros
- This macro provides a convenient constructor for a
ChannelEvent
. It is called with a topic, an event, and an optional inline json payload. - Construct a
serde_json::Value
from a JSON literal.
Structs
- Trillium handler containing a
ChannelHandler
- Channel-wide event broadcaster and subscriber
- Communicate with the connected client.
- A ChannelConn is a wrapper around a [
WebSocketConn
] that also contains aChannelClient
- The messages passed between server and connected clients.
Enums
- The phoenix channel “protocol” version
Traits
- Trait for you to implement in order to define a
Channel
.
Functions
- Constructs a new
Channel
trillium handler from the providedChannelHandler
. This is an alias forChannel::new