How to send websocket messages between Events in Tauri? #4926
-
How can I send a message from the backend websocket Tauri to the web app via Event, and then receive the message via Event and send to the websocket? The client() function receives messages without problems only when it is in But unfortunately the websocket is not receiving any messages now. And trying to send a message from Event to websocket displays an error:
PS. I have to use websocket on the backend side due to the possibility of setting Header Origin. Here is my code: #![cfg_attr(
all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
)]
use tauri::Manager;
use tokio::net::{TcpListener, TcpStream};
use futures_util::{future, SinkExt, StreamExt, TryStreamExt};
use tokio_tungstenite::{
connect_async,
accept_async,
tungstenite::{Result},
};
use http::Request;
use tokio::sync::oneshot;
use futures::{
future::FutureExt, // for `.fuse()`
pin_mut,
select,
};
use tokio::io::AsyncWriteExt;
use std::io;
use std::net::SocketAddr;
use std::thread;
use tokio::spawn;
use tokio::task;
use std::sync::{Arc, Mutex};
use tauri::{AppHandle, InvokePayload, InvokeResponder, InvokeResponse, Runtime, Window};
use tokio_tungstenite::{tungstenite::protocol::Message};
#[derive(Clone, serde::Serialize)]
struct Payload {
message: String,
}
async fn client<R: Runtime>(app_handle: AppHandle<R>) -> Result<()> {
let app = app_handle.clone();
let request = Request::builder()
.method("GET")
.header("Host", "demo.piesocket.com")
// .header("Origin", "https://example.com/")
.header("Connection", "Upgrade")
.header("Upgrade", "websocket")
.header("Sec-WebSocket-Version", "13")
.header("Sec-WebSocket-Key", tungstenite::handshake::client::generate_key())
.uri("wss://demo.piesocket.com/v3/channel_1?api_key=VCXCEuvhGcBDP7XhiJJUDvR1e1D3eiVjgZ9VRiaV¬ify_self")
.body(())?;
let (mut ws_remote, _) = connect_async(request).await?;
let (mut write_remote, mut read_remote) = ws_remote.split();
app.listen_global("msg", move |event| {
write_remote.send(Message::text(event.payload().unwrap()));
// cannot borrow `write_remote` as mutable
});
while let Some(msg) = read_remote.next().await {
let msg = msg?;
if msg.is_text() || msg.is_binary() {
println!("{}", msg) // print nothing
// app.emit_all("msg", Payload { message: msg.to_string() });
}
};
Result::<(), tungstenite::Error>::Ok(())
}
fn main() {
// tauri::async_runtime::spawn(client());
tauri::Builder::default()
.setup(|app| {
// client(app);
client(app.handle());
Ok(())
})
// .plugin(PluginBuilder::default().build())
.run(tauri::generate_context!())
.expect("failed to run app");
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Hmm the first idea that comes to mind is to wrap write_emote in an |
Beta Was this translation helpful? Give feedback.
Hmm the first idea that comes to mind is to wrap write_emote in an
Arc<Mutex<>>
so that you can move it into the event handler 🤔