use crate::actor::context::ActorContext;
use crate::actor::message::{Handler, Message};
use crate::actor::Actor;
use crate::remote::net::codec::NetworkCodec;
use crate::remote::net::message::ClientEvent;
use crate::remote::net::StreamMessage;
use futures::SinkExt;
use std::collections::HashMap;
use tokio_util::codec::FramedWrite;
use uuid::Uuid;
pub struct RemoteSession {
id: Uuid,
write: FramedWrite<tokio::io::WriteHalf<tokio::net::TcpStream>, NetworkCodec>,
}
impl RemoteSession {
pub fn new(
id: Uuid,
write: FramedWrite<tokio::io::WriteHalf<tokio::net::TcpStream>, NetworkCodec>,
) -> RemoteSession {
RemoteSession { id, write }
}
}
pub struct RemoteSessionStore {
sessions: HashMap<Uuid, RemoteSession>,
}
impl Actor for RemoteSessionStore {}
impl RemoteSessionStore {
pub fn new() -> RemoteSessionStore {
RemoteSessionStore {
sessions: HashMap::new(),
}
}
}
pub struct NewSession(pub RemoteSession);
pub struct SessionWrite(pub Uuid, pub ClientEvent);
pub struct SessionClosed(pub Uuid);
impl Message for NewSession {
type Result = ();
}
impl Message for SessionClosed {
type Result = ();
}
impl Message for SessionWrite {
type Result = ();
}
#[async_trait]
impl Handler<NewSession> for RemoteSessionStore {
async fn handle(&mut self, message: NewSession, _ctx: &mut ActorContext) {
trace!(target: "SessionStore", "new session {}", &message.0.id);
self.sessions.insert(message.0.id, message.0);
}
}
#[async_trait]
impl Handler<SessionClosed> for RemoteSessionStore {
async fn handle(&mut self, message: SessionClosed, _ctx: &mut ActorContext) {
self.sessions.remove(&message.0);
trace!(target: "SessionStore", "disposed session {}", &message.0);
}
}
#[async_trait]
impl Handler<SessionWrite> for RemoteSessionStore {
async fn handle(&mut self, message: SessionWrite, _ctx: &mut ActorContext) {
match self.sessions.get_mut(&message.0) {
Some(session) => {
trace!(target: "RemoteSession", "writing to session {}", &message.0);
match message.1.write_to_bytes() {
Some(msg) => {
trace!(target: "RemoteSession", "message encoded");
if session.write.send(msg).await.is_ok() {
trace!(target: "RemoteSession", "message sent");
} else {
error!(target: "RemoteSession", "failed to send message");
}
}
None => {
warn!(target: "RemoteSession", "failed to encode message");
}
}
}
None => {
warn!(target: "RemoteSession", "attempted to write to session that couldn't be found");
}
}
}
}