summaryrefslogtreecommitdiffhomepage
path: root/talpid_ipc/src/lib.rs
blob: 3ef9bf47338a4f243748e2c1ea5ec5302769252f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#[macro_use]
extern crate error_chain;
#[macro_use]
extern crate log;

extern crate serde;
#[macro_use]
extern crate serde_json;

extern crate jsonrpc_core;
extern crate jsonrpc_ws_server;
extern crate ws;
extern crate url;

use jsonrpc_core::{MetaIoHandler, Metadata};
use jsonrpc_ws_server::{MetaExtractor, NoopExtractor, Server, ServerBuilder};

use std::net::{IpAddr, Ipv4Addr, SocketAddr};


mod client;
pub use client::*;

/// An Id created by the Ipc server that the client can use to connect to it
pub type IpcServerId = String;

error_chain!{
    errors {
        IpcServerError {
            description("Error in IPC server")
        }
    }
}


pub struct IpcServer {
    address: String,
    server: Server,
}

impl IpcServer {
    pub fn start<M: Metadata>(handler: MetaIoHandler<M>) -> Result<Self> {
        Self::start_with_metadata(handler, NoopExtractor)
    }

    pub fn start_with_metadata<M, E>(handler: MetaIoHandler<M>, meta_extractor: E) -> Result<Self>
        where M: Metadata,
              E: MetaExtractor<M>
    {
        let listen_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 0);
        ServerBuilder::new(handler)
            .session_meta_extractor(meta_extractor)
            .start(&listen_addr)
            .map(
                |server| {
                    IpcServer {
                        address: format!("ws://{}", server.addr()),
                        server: server,
                    }
                },
            )
            .chain_err(|| ErrorKind::IpcServerError)
    }

    /// Returns the localhost address this `IpcServer` is listening on.
    pub fn address(&self) -> &str {
        &self.address
    }

    /// Creates a handle bound to this `IpcServer` that can be used to shut it down.
    pub fn close_handle(&self) -> CloseHandle {
        CloseHandle(self.server.close_handle())
    }

    /// Consumes the server and waits for it to finish. Get an `CloseHandle` before calling this
    /// if you want to be able to shut the server down.
    pub fn wait(self) -> Result<()> {
        self.server.wait().chain_err(|| ErrorKind::IpcServerError)
    }
}

#[derive(Clone)]
pub struct CloseHandle(jsonrpc_ws_server::CloseHandle);

impl CloseHandle {
    pub fn close(self) {
        self.0.close();
    }
}