Files
chatmail-core/deltachat-jsonrpc/src/webserver.rs
link2xt 514074de8b JSON-RPC: retrieve events via long polling
This way is more compatible to JSON-RPC libraries
that do not support receiving notifications from the server
and allows describing event types in the OpenRPC specification.

Event thread converting events to notifications in the FFI
is removed, so it is now possible to construct a dc_jsonrpc_instance_t
while still retrieving events via dc_event_emitter_t.
2023-04-22 16:42:59 +00:00

48 lines
1.6 KiB
Rust

use std::net::SocketAddr;
use std::path::PathBuf;
use axum::{extract::ws::WebSocketUpgrade, response::Response, routing::get, Extension, Router};
use yerpc::axum::handle_ws_rpc;
use yerpc::{RpcClient, RpcSession};
mod api;
use api::{Accounts, CommandApi};
const DEFAULT_PORT: u16 = 20808;
#[tokio::main(flavor = "multi_thread")]
async fn main() -> Result<(), std::io::Error> {
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
let path = std::env::var("DC_ACCOUNTS_PATH").unwrap_or_else(|_| "./accounts".to_string());
let port = std::env::var("DC_PORT")
.map(|port| port.parse::<u16>().expect("DC_PORT must be a number"))
.unwrap_or(DEFAULT_PORT);
log::info!("Starting with accounts directory `{path}`.");
let accounts = Accounts::new(PathBuf::from(&path)).await.unwrap();
let state = CommandApi::new(accounts);
let app = Router::new()
.route("/ws", get(handler))
.layer(Extension(state.clone()));
tokio::spawn(async move {
state.accounts.read().await.start_io().await;
});
let addr = SocketAddr::from(([127, 0, 0, 1], port));
log::info!("JSON-RPC WebSocket server listening on {}", addr);
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
Ok(())
}
async fn handler(ws: WebSocketUpgrade, Extension(api): Extension<CommandApi>) -> Response {
let (client, out_receiver) = RpcClient::new();
let session = RpcSession::new(client.clone(), api.clone());
handle_ws_rpc(ws, out_receiver, session).await
}