witty_jsonrpc/transports/
http.rs

1use std::sync::{Arc, Mutex};
2
3use jsonrpc_http_server::{Server, ServerBuilder};
4use jsonrpc_ws_server::tokio;
5
6use crate::{
7    handler::Handler,
8    transports::{Transport, TransportError},
9};
10
11/// Settings needed for constructing an `HttpTransport`.
12#[derive(Clone, Debug)]
13pub struct HttpTransportSettings {
14    /// An IP or address to bind the HTTP listener to.
15    pub address: String,
16}
17
18/// A JSON-RPC over HTTP transport built around the `jsonrpc_http_server` library.
19pub struct HttpTransport<H>
20where
21    H: Handler,
22{
23    settings: HttpTransportSettings,
24    server_builder: Option<ServerBuilder<H::Metadata>>,
25    server: Option<Server>,
26}
27
28impl<H> HttpTransport<H>
29where
30    H: Handler,
31{
32    /// Create a new instance of this transport.
33    pub fn new(settings: HttpTransportSettings) -> Self {
34        Self {
35            settings,
36            server_builder: None,
37            server: None,
38        }
39    }
40}
41
42impl<H> Transport<H> for HttpTransport<H>
43where
44    H: Handler,
45    H::Metadata: Default,
46{
47    fn requires_reset(&self) -> bool {
48        true
49    }
50
51    fn running(&self) -> bool {
52        self.server.is_some()
53    }
54
55    fn set_handler(
56        &mut self,
57        handler: Arc<Mutex<H>>,
58        runtime: Option<tokio::runtime::Handle>,
59    ) -> Result<(), TransportError> {
60        let handler = (*handler.lock().unwrap()).as_meta_io_handler();
61
62        let mut builder = ServerBuilder::new(handler);
63
64        if let Some(runtime) = runtime {
65            builder = builder.event_loop_executor(runtime);
66        }
67
68        self.server_builder = Some(builder);
69
70        Ok(())
71    }
72
73    fn start(&mut self) -> Result<(), TransportError> {
74        if self.server.is_some() {
75            return Ok(());
76        }
77
78        let builder = self
79            .server_builder
80            .take()
81            .ok_or(TransportError::NoHandler)?;
82        let socket_addr = self.settings.address.parse::<std::net::SocketAddr>()?;
83        self.server = Some(builder.start_http(&socket_addr)?);
84
85        Ok(())
86    }
87
88    fn stop(&mut self) -> Result<(), TransportError> {
89        match self.server.take() {
90            None => Ok(()),
91            Some(server) => {
92                server.close();
93                Ok(())
94            }
95        }
96    }
97}