use ws::{listen, Handler, Sender, Result, Message, Handshake, CloseCode, Error}; use serde_cbor::{to_vec}; use std::env; use r2d2::{Pool}; use r2d2::{PooledConnection}; use r2d2_postgres::{TlsMode, PostgresConnectionManager}; static DB_POOL_SIZE: u32 = 20; pub type Db = PooledConnection; use rpc::{Rpc}; struct Server { out: Sender, rpc: Rpc, db: Pool, } #[derive(Debug,Clone,Serialize,Deserialize)] struct RpcErrorResponse { err: String } impl Handler for Server { fn on_open(&mut self, _: Handshake) -> Result<()> { println!("somebody joined"); Ok(()) } fn on_message(&mut self, msg: Message) -> Result<()> { let db = self.db.get().expect("unable to get db connection"); match self.rpc.receive(msg, &db, &self.out) { Ok(reply) => { let response = to_vec(&reply) .expect("failed to serialize response"); self.out.send(response) }, Err(e) => { println!("{:?}", e); let response = to_vec(&RpcErrorResponse { err: e.to_string() }) .expect("failed to serialize error response"); self.out.send(response) } } } fn on_close(&mut self, code: CloseCode, reason: &str) { match code { CloseCode::Normal => println!("The client is done with the connection."), CloseCode::Away => println!("The client is leaving the site."), CloseCode::Abnormal => println!( "Closing handshake failed! Unable to obtain closing status from client."), _ => println!("The client encountered an error: {}", reason), } } fn on_error(&mut self, err: Error) { println!("The server encountered an error: {:?}", err); } } pub fn db_connection(url: String) -> Pool { let manager = PostgresConnectionManager::new(url, TlsMode::None) .expect("could not instantiate pg manager"); Pool::builder() .max_size(DB_POOL_SIZE) .build(manager) .expect("Failed to create pool.") } pub fn start() { let database_url = env::var("DATABASE_URL") .expect("DATABASE_URL must be set"); let pool = db_connection(database_url); listen("127.0.0.1:40000", |out| { Server { out, rpc: Rpc {}, db: pool.clone() } }).unwrap(); }