jsonrpc_ws_server/
server_builder.rs

1use std::net::SocketAddr;
2use std::sync::Arc;
3
4use crate::core;
5use crate::server_utils::cors::Origin;
6use crate::server_utils::hosts::{DomainsValidation, Host};
7use crate::server_utils::reactor::{self, UninitializedExecutor};
8use crate::server_utils::session::SessionStats;
9
10use crate::error::Result;
11use crate::metadata::{MetaExtractor, NoopExtractor};
12use crate::server::Server;
13use crate::session;
14
15/// Builder for `WebSockets` server
16pub struct ServerBuilder<M: core::Metadata, S: core::Middleware<M>> {
17	handler: Arc<core::MetaIoHandler<M, S>>,
18	meta_extractor: Arc<dyn MetaExtractor<M>>,
19	allowed_origins: Option<Vec<Origin>>,
20	allowed_hosts: Option<Vec<Host>>,
21	request_middleware: Option<Arc<dyn session::RequestMiddleware>>,
22	session_stats: Option<Arc<dyn SessionStats>>,
23	executor: UninitializedExecutor,
24	max_connections: usize,
25	max_payload_bytes: usize,
26	max_in_buffer_capacity: usize,
27	max_out_buffer_capacity: usize,
28}
29
30impl<M: core::Metadata + Default, S: core::Middleware<M>> ServerBuilder<M, S>
31where
32	S::Future: Unpin,
33	S::CallFuture: Unpin,
34{
35	/// Creates new `ServerBuilder`
36	pub fn new<T>(handler: T) -> Self
37	where
38		T: Into<core::MetaIoHandler<M, S>>,
39	{
40		Self::with_meta_extractor(handler, NoopExtractor)
41	}
42}
43
44impl<M: core::Metadata, S: core::Middleware<M>> ServerBuilder<M, S>
45where
46	S::Future: Unpin,
47	S::CallFuture: Unpin,
48{
49	/// Creates new `ServerBuilder`
50	pub fn with_meta_extractor<T, E>(handler: T, extractor: E) -> Self
51	where
52		T: Into<core::MetaIoHandler<M, S>>,
53		E: MetaExtractor<M>,
54	{
55		ServerBuilder {
56			handler: Arc::new(handler.into()),
57			meta_extractor: Arc::new(extractor),
58			allowed_origins: None,
59			allowed_hosts: None,
60			request_middleware: None,
61			session_stats: None,
62			executor: UninitializedExecutor::Unspawned,
63			max_connections: 100,
64			max_payload_bytes: 5 * 1024 * 1024,
65			max_in_buffer_capacity: 10 * 1024 * 1024,
66			max_out_buffer_capacity: 10 * 1024 * 1024,
67		}
68	}
69
70	/// Utilize existing event loop executor to poll RPC results.
71	pub fn event_loop_executor(mut self, executor: reactor::TaskExecutor) -> Self {
72		self.executor = UninitializedExecutor::Shared(executor);
73		self
74	}
75
76	/// Sets a meta extractor.
77	pub fn session_meta_extractor<T: MetaExtractor<M>>(mut self, extractor: T) -> Self {
78		self.meta_extractor = Arc::new(extractor);
79		self
80	}
81
82	/// Allowed origins.
83	pub fn allowed_origins(mut self, allowed_origins: DomainsValidation<Origin>) -> Self {
84		self.allowed_origins = allowed_origins.into();
85		self
86	}
87
88	/// Allowed hosts.
89	pub fn allowed_hosts(mut self, allowed_hosts: DomainsValidation<Host>) -> Self {
90		self.allowed_hosts = allowed_hosts.into();
91		self
92	}
93
94	/// Session stats
95	pub fn session_stats<T: SessionStats>(mut self, stats: T) -> Self {
96		self.session_stats = Some(Arc::new(stats));
97		self
98	}
99
100	/// Sets a request middleware. Middleware will be invoked before each handshake request.
101	/// You can either terminate the handshake in the middleware or run a default behaviour after.
102	pub fn request_middleware<T: session::RequestMiddleware>(mut self, middleware: T) -> Self {
103		self.request_middleware = Some(Arc::new(middleware));
104		self
105	}
106
107	/// Maximal number of concurrent connections this server supports.
108	/// Default: 100
109	pub fn max_connections(mut self, max_connections: usize) -> Self {
110		self.max_connections = max_connections;
111		self
112	}
113
114	/// Maximal size of the payload (in bytes)
115	/// Default: 5MB
116	pub fn max_payload(mut self, max_payload_bytes: usize) -> Self {
117		self.max_payload_bytes = max_payload_bytes;
118		self
119	}
120
121	/// The maximum size to which the incoming buffer can grow.
122	/// Default: 10,485,760
123	pub fn max_in_buffer_capacity(mut self, max_in_buffer_capacity: usize) -> Self {
124		self.max_in_buffer_capacity = max_in_buffer_capacity;
125		self
126	}
127
128	/// The maximum size to which the outgoing buffer can grow.
129	/// Default: 10,485,760
130	pub fn max_out_buffer_capacity(mut self, max_out_buffer_capacity: usize) -> Self {
131		self.max_out_buffer_capacity = max_out_buffer_capacity;
132		self
133	}
134
135	/// Starts a new `WebSocket` server in separate thread.
136	/// Returns a `Server` handle which closes the server when droped.
137	pub fn start(self, addr: &SocketAddr) -> Result<Server> {
138		Server::start(
139			addr,
140			self.handler,
141			self.meta_extractor,
142			self.allowed_origins,
143			self.allowed_hosts,
144			self.request_middleware,
145			self.session_stats,
146			self.executor,
147			self.max_connections,
148			self.max_payload_bytes,
149			self.max_in_buffer_capacity,
150			self.max_out_buffer_capacity,
151		)
152	}
153}
154
155#[cfg(test)]
156mod tests {
157	use super::*;
158
159	fn basic_server_builder() -> ServerBuilder<(), jsonrpc_core::middleware::Noop> {
160		let io = core::IoHandler::default();
161		ServerBuilder::new(io)
162	}
163	#[test]
164	fn config_usize_vals_have_correct_defaults() {
165		let server = basic_server_builder();
166
167		assert_eq!(server.max_connections, 100);
168		assert_eq!(server.max_payload_bytes, 5 * 1024 * 1024);
169		assert_eq!(server.max_in_buffer_capacity, 10 * 1024 * 1024);
170		assert_eq!(server.max_out_buffer_capacity, 10 * 1024 * 1024);
171	}
172
173	#[test]
174	fn config_usize_vals_can_be_set() {
175		let server = basic_server_builder();
176
177		// We can set them individually
178		let server = server.max_connections(10);
179		assert_eq!(server.max_connections, 10);
180
181		let server = server.max_payload(29);
182		assert_eq!(server.max_payload_bytes, 29);
183
184		let server = server.max_in_buffer_capacity(38);
185		assert_eq!(server.max_in_buffer_capacity, 38);
186
187		let server = server.max_out_buffer_capacity(47);
188		assert_eq!(server.max_out_buffer_capacity, 47);
189
190		// Setting values consecutively does not impact other values
191		assert_eq!(server.max_connections, 10);
192		assert_eq!(server.max_payload_bytes, 29);
193		assert_eq!(server.max_in_buffer_capacity, 38);
194		assert_eq!(server.max_out_buffer_capacity, 47);
195	}
196}