todo
- received first by the OS
- then by websocket server code we don't control
- eventually handed over to us
- we parse the message enough to figure out the topic
- use router to find the matching Channel
- is this a join request? (if so, separate business logic for that, call a join method)
- check that this ws connection is actually allowed to send stuff to this channel (???)
- deserialize the message payload fully
- make sure we're not delivering multiple messages simultaneously (using a mutex or an mpsc channel)
- actually deliver the message to the Channel impl, finally
Then the Channel can do whatever it wants with that.
The Router can have a bunch of channels of all different types. How do we get messages decoded to the right types and delivered?
struct IncomingMessage {
topic: String,
event: String,
payload: serde_json::value::Value,
}
trait MessageReceiver {
fn receive(&mut self, message: IncomingMessage) -> Result<?, ?>;
}
// that way, we can have a single data structure with many MessageReceivers of different types
struct Router
receivers: Arc<RwLock<HashMap<String, Box<dyn MessageReceiver>>>>,
}
// now we just need a way to treat any Channel as a MessageReceiver:
struct ChannelAsMessageReceiver<C: Channel> {
channel: C,
}
impl<C: Channel> MessageReceiver for ChannelAsMessageReceiver<C> {
fn receive(&mut self, message: IncomingMessage) -> Result<?, ?> {
let payload: C::Message = serde_json::from_value(message.payload)?;
self.channel.handle_in(payload)
}
}
impl Router {
fn add_channel<C: Channel>(&mut self, channel: C) {
let id = channel.id();
let receiver = Box::new(ChannelAsMessageReceiver { channel });
self.receivers.insert(id, receiver);
}
}
todo