1
0

ws_receiver.rs 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. use crate::DevserverMsg;
  2. use futures_util::{SinkExt, StreamExt};
  3. use tokio::net::TcpStream;
  4. use tokio_tungstenite::{
  5. tungstenite::{Message, Result as TtResult},
  6. MaybeTlsStream, WebSocketStream,
  7. };
  8. pub fn connect(mut callback: impl FnMut(DevserverMsg) + Send + 'static) {
  9. tokio::spawn(async move {
  10. let Some(Ok(mut recv)) = NativeReceiver::create_from_cli().await else {
  11. return;
  12. };
  13. while let Some(msg) = recv.next().await {
  14. match msg {
  15. Ok(msg) => callback(msg),
  16. Err(_e) => {}
  17. }
  18. }
  19. });
  20. }
  21. /// A receiver for messages from the devserver
  22. ///
  23. /// Calling `next` will watch the channel for the next valid message from the devserver
  24. pub struct NativeReceiver {
  25. socket: WebSocketStream<MaybeTlsStream<TcpStream>>,
  26. }
  27. impl NativeReceiver {
  28. /// Connect to the devserver
  29. async fn create(url: String) -> TtResult<Self> {
  30. let (socket, _ws) = tokio_tungstenite::connect_async(&url).await?;
  31. Ok(Self { socket })
  32. }
  33. /// Connect to the devserver with an address from the CLI. Returns None if the current application was not run with the CLI
  34. pub async fn create_from_cli() -> Option<TtResult<Self>> {
  35. let cli_args = dioxus_cli_config::RuntimeCLIArguments::from_cli()?;
  36. let addr = cli_args.cli_address();
  37. Some(Self::create(format!("ws://{addr}/_dioxus")).await)
  38. }
  39. /// Wait for the next message from the devserver
  40. ///
  41. /// Returns None when the connection is closed or socket.next() returns None
  42. pub async fn next(&mut self) -> Option<TtResult<DevserverMsg>> {
  43. loop {
  44. let res = self.socket.next().await?;
  45. match res {
  46. Ok(res) => match res {
  47. Message::Text(text) => {
  48. // let leaked: &'static str = Box::leak(text.into_boxed_str());
  49. let msg = serde_json::from_str::<DevserverMsg>(&text);
  50. if let Ok(msg) = msg {
  51. return Some(Ok(msg));
  52. }
  53. }
  54. // send a pong
  55. Message::Ping(_) => {
  56. let _ = self.socket.send(Message::Pong(vec![])).await;
  57. }
  58. Message::Close(_) => return None,
  59. Message::Binary(_) => {}
  60. Message::Pong(_) => {}
  61. Message::Frame(_) => {}
  62. },
  63. Err(e) => return Some(Err(e)),
  64. };
  65. }
  66. }
  67. }