jsonrpc.rs 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2023 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. use async_std::{net::TcpListener, sync::Arc, task};
  19. use async_trait::async_trait;
  20. use serde_json::{json, Value};
  21. use smol::channel::{Receiver, Sender};
  22. use url::Url;
  23. use darkfi::{
  24. net::transport::Listener,
  25. rpc::{
  26. client::RpcClient,
  27. jsonrpc::*,
  28. server::{accept, RequestHandler},
  29. },
  30. Result,
  31. };
  32. struct RpcSrv {
  33. stop_sub: (Sender<()>, Receiver<()>),
  34. }
  35. impl RpcSrv {
  36. async fn pong(&self, id: Value, _params: &[Value]) -> JsonResult {
  37. JsonResponse::new(json!("pong"), id).into()
  38. }
  39. async fn kill(&self, id: Value, _params: &[Value]) -> JsonResult {
  40. self.stop_sub.0.send(()).await.unwrap();
  41. JsonResponse::new(json!("bye"), id).into()
  42. }
  43. }
  44. #[async_trait]
  45. impl RequestHandler for RpcSrv {
  46. async fn handle_request(&self, req: JsonRequest) -> JsonResult {
  47. let params = req.params.as_array().unwrap();
  48. match req.method.as_str() {
  49. Some("ping") => return self.pong(req.id, params).await,
  50. Some("kill") => return self.kill(req.id, params).await,
  51. Some(_) | None => return JsonError::new(ErrorCode::MethodNotFound, None, req.id).into(),
  52. }
  53. }
  54. }
  55. #[async_std::test]
  56. async fn jsonrpc_reqrep() -> Result<()> {
  57. // Find an available port
  58. let listener = TcpListener::bind("127.0.0.1:0").await?;
  59. let sockaddr = listener.local_addr()?;
  60. let endpoint = Url::parse(&format!("tcp://127.0.0.1:{}", sockaddr.port()))?;
  61. drop(listener);
  62. let rpcsrv = Arc::new(RpcSrv { stop_sub: smol::channel::unbounded() });
  63. let listener = Listener::new(endpoint.clone()).await?.listen().await?;
  64. task::spawn(async move {
  65. while let Ok((stream, peer_addr)) = listener.next().await {
  66. let _rh = rpcsrv.clone();
  67. task::spawn(async move {
  68. let _ = accept(stream, peer_addr.clone(), _rh).await;
  69. });
  70. }
  71. });
  72. let client = RpcClient::new(endpoint, None).await?;
  73. let req = JsonRequest::new("ping", json!([]));
  74. let rep = client.request(req).await?;
  75. let rep = rep.as_str().unwrap();
  76. assert_eq!(rep, "pong");
  77. let req = JsonRequest::new("kill", json!([]));
  78. let rep = client.request(req).await?;
  79. let rep = rep.as_str().unwrap();
  80. assert_eq!(rep, "bye");
  81. Ok(())
  82. }