use super::super::{ServiceCallback, WsData};
use super::msg::{ActorMsg, ConnInfo, Connect, Disconnect, Request, Response};
use super::msg_bin::BinRecvMessage;
use actix::prelude::{Actor, Context, Handler, Recipient};
use dashmap::{DashMap, DashSet};
use std::sync::Arc;
use tracing::{error, info};
type Socket = Recipient<Response>;
#[derive(Clone)]
pub struct Lobby {
pub consumer: Arc<dyn ServiceCallback>,
pub sessions: Arc<DashMap<String, (ConnInfo, Socket)>>, pub rooms: Arc<DashMap<String, DashSet<String>>>, }
impl Actor for Lobby {
type Context = Context<Self>;
fn started(&mut self, ctx: &mut Self::Context) {
let mailbox_size = 2048;
ctx.set_mailbox_capacity(mailbox_size);
info!("set lobby mailbox size as {}", mailbox_size);
}
}
impl Lobby {
pub fn new(consumer: Arc<dyn ServiceCallback>) -> Lobby {
let lobby = Lobby {
consumer: consumer,
sessions: Arc::new(DashMap::new()),
rooms: Arc::new(DashMap::new()),
};
lobby
}
pub fn send_response(&self, message: Response, id_to: &String) {
if let Some(socket_recipient) = self.sessions.get(id_to) {
let _ = socket_recipient.1.do_send(message);
} else {
error!(
"attempting to send message but couldn't find user id: {}",
id_to
);
}
}
pub fn send_group_json(&self, connid: String, evt_data: String) {
self.rooms
.get(&connid)
.unwrap()
.iter()
.for_each(|connid_actor| {
let connid_actor = connid_actor.clone();
let mut resp = Response::default();
resp.status = true;
resp.text = Some(evt_data.clone());
self.send_response(resp, &connid_actor);
});
}
pub fn send_group_binary(&self, connid: String, evt_data: Vec<u8>) {
self.rooms
.get(&connid)
.unwrap()
.iter()
.for_each(|connid_actor| {
let connid_actor = connid_actor.clone();
let mut resp = Response::default();
resp.status = true;
resp.binary = Some(evt_data.clone());
self.send_response(resp, &connid_actor);
});
}
}
impl Handler<Connect> for Lobby {
type Result = anyhow::Result<ActorMsg>;
fn handle(&mut self, msg: Connect, _: &mut Context<Self>) -> Self::Result {
futures::executor::block_on(async {
self.consumer
.wsdata(WsData::WsConnect { data: msg }, self.consumer.clone())
.await
})
}
}
impl Handler<Disconnect> for Lobby {
type Result = anyhow::Result<ActorMsg>;
fn handle(&mut self, msg: Disconnect, _: &mut Context<Self>) -> Self::Result {
futures::executor::block_on(async {
self.consumer
.wsdata(WsData::WsDisconnect { data: msg }, self.consumer.clone())
.await
})
}
}
impl Handler<Request> for Lobby {
type Result = anyhow::Result<ActorMsg>;
fn handle(&mut self, msg: Request, _ctx: &mut Context<Self>) -> Self::Result {
futures::executor::block_on(async {
self.consumer
.wsdata(WsData::WsRequest { data: msg }, self.consumer.clone())
.await
})
}
}
impl Handler<BinRecvMessage> for Lobby {
type Result = anyhow::Result<ActorMsg>;
fn handle(&mut self, msg: BinRecvMessage, _ctx: &mut Context<Self>) -> Self::Result {
futures::executor::block_on(async {
self.consumer
.wsdata(WsData::WsBinMsg { data: msg }, self.consumer.clone())
.await
})
}
}