83 lines
2.4 KiB
Rust
Executable File
83 lines
2.4 KiB
Rust
Executable File
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<PostgresConnectionManager>;
|
|
|
|
use rpc::{Rpc};
|
|
|
|
struct Server {
|
|
out: Sender,
|
|
rpc: Rpc,
|
|
db: Pool<PostgresConnectionManager>,
|
|
}
|
|
|
|
#[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<PostgresConnectionManager> {
|
|
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();
|
|
}
|