95 lines
2.2 KiB
Rust
95 lines
2.2 KiB
Rust
use actix::prelude::*;
|
|
use log::info;
|
|
use rand::prelude::*;
|
|
use std::collections::HashMap;
|
|
use tokio::net::{TcpListener, TcpStream};
|
|
use tokio_tungstenite::WebSocketStream;
|
|
|
|
pub struct NetworkConnection {
|
|
conn_id: u64,
|
|
connected: bool,
|
|
stream: WebSocketStream<TcpStream>,
|
|
manager: Addr<NetworkManager>,
|
|
}
|
|
|
|
impl Actor for NetworkConnection {
|
|
type Context = Context<NetworkConnection>;
|
|
|
|
fn started(&mut self, ctx: &mut Self::Context) {
|
|
// Send manager my info and get a connection ID assigned
|
|
let addr = ctx.address();
|
|
self.manager
|
|
.send(ClientConnected { addr })
|
|
.into_actor(self)
|
|
.then(move |res, act, _| {
|
|
act.conn_id = res.unwrap();
|
|
act.connected = true;
|
|
async {}.into_actor(act)
|
|
})
|
|
.wait(ctx);
|
|
//TODO Start recv/send loop
|
|
}
|
|
}
|
|
|
|
#[derive(Message)]
|
|
#[rtype(result = "u64")]
|
|
struct ClientConnected {
|
|
addr: Addr<NetworkConnection>,
|
|
}
|
|
|
|
pub struct NetworkManager {
|
|
bind: String,
|
|
clients: HashMap<u64, Addr<NetworkConnection>>,
|
|
}
|
|
|
|
impl Actor for NetworkManager {
|
|
type Context = Context<NetworkManager>;
|
|
|
|
fn started(&mut self, ctx: &mut Self::Context) {
|
|
Arbiter::spawn(listen_websocket(self.bind.clone(), ctx.address()));
|
|
}
|
|
}
|
|
|
|
impl Handler<ClientConnected> for NetworkManager {
|
|
type Result = u64;
|
|
fn handle(&mut self, msg: ClientConnected, _ctx: &mut Self::Context) -> Self::Result {
|
|
let client_id = rand::thread_rng().gen();
|
|
self.clients.insert(client_id, msg.addr);
|
|
client_id
|
|
}
|
|
}
|
|
|
|
impl NetworkManager {
|
|
pub fn new(bind: String) -> Self {
|
|
NetworkManager {
|
|
bind,
|
|
clients: HashMap::new(),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub async fn listen_websocket(bind: String, manager: Addr<NetworkManager>) {
|
|
let try_socket = TcpListener::bind(&bind).await;
|
|
let mut listener = try_socket.expect("Failed to bind");
|
|
info!("Listening on: {}", bind);
|
|
|
|
while let Ok((stream, _)) = listener.accept().await {
|
|
let addr = stream
|
|
.peer_addr()
|
|
.expect("connected streams should have a peer address");
|
|
info!("Peer address: {}", addr);
|
|
|
|
let stream = tokio_tungstenite::accept_async(stream)
|
|
.await
|
|
.expect("Error during the websocket handshake occurred");
|
|
info!("New WebSocket connection: {}", addr);
|
|
|
|
NetworkConnection::create(|_ctx| NetworkConnection {
|
|
conn_id: 0,
|
|
connected: false,
|
|
stream,
|
|
manager: manager.clone(),
|
|
});
|
|
}
|
|
}
|