feat: add togglePin & switch server (#166)

* feat: add togglePin

* proxy websocket poc

* feat: switch server

* merge: merge switch ws server

* feat: add switch server

---------

Co-authored-by: medcl <m@medcl.net>
This commit is contained in:
BiggerRain
2025-02-21 18:57:32 +08:00
committed by GitHub
parent ca9adb515b
commit a383ec3273
21 changed files with 925 additions and 233 deletions

319
src-tauri/Cargo.lock generated
View File

@@ -74,6 +74,56 @@ dependencies = [
"libc",
]
[[package]]
name = "anstream"
version = "0.6.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
[[package]]
name = "anstyle-parse"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
dependencies = [
"anstyle",
"once_cell",
"windows-sys 0.59.0",
]
[[package]]
name = "anyhow"
version = "1.0.89"
@@ -660,9 +710,13 @@ dependencies = [
"async-trait",
"base64 0.13.1",
"dirs 5.0.1",
"env_logger",
"futures",
"futures-util",
"fuzzy_prefix_search",
"hostname",
"http 1.1.0",
"hyper 0.14.32",
"lazy_static",
"log",
"notify",
@@ -693,6 +747,10 @@ dependencies = [
"tauri-plugin-websocket",
"thiserror 1.0.64",
"tokio",
"tokio-native-tls",
"tokio-tungstenite 0.20.1",
"tungstenite 0.24.0",
"url",
"walkdir",
]
@@ -726,6 +784,12 @@ dependencies = [
"objc",
]
[[package]]
name = "colorchoice"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
[[package]]
name = "combine"
version = "4.6.7"
@@ -1296,6 +1360,29 @@ dependencies = [
"syn 2.0.90",
]
[[package]]
name = "env_filter"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0"
dependencies = [
"log",
"regex",
]
[[package]]
name = "env_logger"
version = "0.11.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcaee3d8e3cfc3fd92428d477bc97fc29ec8716d180c0d74c643bb26166660e0"
dependencies = [
"anstream",
"anstyle",
"env_filter",
"humantime",
"log",
]
[[package]]
name = "equivalent"
version = "1.0.1"
@@ -1949,7 +2036,7 @@ dependencies = [
"fnv",
"futures-core",
"futures-sink",
"http",
"http 1.1.0",
"indexmap 2.6.0",
"slab",
"tokio",
@@ -2034,6 +2121,17 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "http"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1"
dependencies = [
"bytes",
"fnv",
"itoa 1.0.11",
]
[[package]]
name = "http"
version = "1.1.0"
@@ -2045,6 +2143,17 @@ dependencies = [
"itoa 1.0.11",
]
[[package]]
name = "http-body"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
dependencies = [
"bytes",
"http 0.2.12",
"pin-project-lite",
]
[[package]]
name = "http-body"
version = "1.0.1"
@@ -2052,7 +2161,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
dependencies = [
"bytes",
"http",
"http 1.1.0",
]
[[package]]
@@ -2063,8 +2172,8 @@ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f"
dependencies = [
"bytes",
"futures-util",
"http",
"http-body",
"http 1.1.0",
"http-body 1.0.1",
"pin-project-lite",
]
@@ -2080,6 +2189,40 @@ version = "1.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946"
[[package]]
name = "httpdate"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "humantime"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
name = "hyper"
version = "0.14.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7"
dependencies = [
"bytes",
"futures-channel",
"futures-core",
"futures-util",
"http 0.2.12",
"http-body 0.4.6",
"httparse",
"httpdate",
"itoa 1.0.11",
"pin-project-lite",
"tokio",
"tower-service",
"tracing",
"want",
]
[[package]]
name = "hyper"
version = "1.4.1"
@@ -2090,8 +2233,8 @@ dependencies = [
"futures-channel",
"futures-util",
"h2",
"http",
"http-body",
"http 1.1.0",
"http-body 1.0.1",
"httparse",
"itoa 1.0.11",
"pin-project-lite",
@@ -2107,15 +2250,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333"
dependencies = [
"futures-util",
"http",
"hyper",
"http 1.1.0",
"hyper 1.4.1",
"hyper-util",
"rustls",
"rustls 0.23.15",
"rustls-pki-types",
"tokio",
"tokio-rustls",
"tokio-rustls 0.26.0",
"tower-service",
"webpki-roots",
"webpki-roots 0.26.6",
]
[[package]]
@@ -2126,7 +2269,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
dependencies = [
"bytes",
"http-body-util",
"hyper",
"hyper 1.4.1",
"hyper-util",
"native-tls",
"tokio",
@@ -2143,9 +2286,9 @@ dependencies = [
"bytes",
"futures-channel",
"futures-util",
"http",
"http-body",
"hyper",
"http 1.1.0",
"http-body 1.0.1",
"hyper 1.4.1",
"pin-project-lite",
"socket2 0.5.7",
"tokio",
@@ -2330,6 +2473,12 @@ dependencies = [
"once_cell",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "itoa"
version = "0.4.8"
@@ -3653,7 +3802,7 @@ dependencies = [
"quinn-proto",
"quinn-udp",
"rustc-hash",
"rustls",
"rustls 0.23.15",
"socket2 0.5.7",
"thiserror 1.0.64",
"tokio",
@@ -3670,7 +3819,7 @@ dependencies = [
"rand 0.8.5",
"ring",
"rustc-hash",
"rustls",
"rustls 0.23.15",
"slab",
"thiserror 1.0.64",
"tinyvec",
@@ -3860,10 +4009,10 @@ dependencies = [
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
"http 1.1.0",
"http-body 1.0.1",
"http-body-util",
"hyper",
"hyper 1.4.1",
"hyper-rustls",
"hyper-tls",
"hyper-util",
@@ -3876,7 +4025,7 @@ dependencies = [
"percent-encoding",
"pin-project-lite",
"quinn",
"rustls",
"rustls 0.23.15",
"rustls-pemfile",
"rustls-pki-types",
"serde",
@@ -3886,7 +4035,7 @@ dependencies = [
"system-configuration",
"tokio",
"tokio-native-tls",
"tokio-rustls",
"tokio-rustls 0.26.0",
"tokio-util",
"tower",
"tower-service",
@@ -3895,7 +4044,7 @@ dependencies = [
"wasm-bindgen-futures",
"wasm-streams",
"web-sys",
"webpki-roots",
"webpki-roots 0.26.6",
"windows-registry 0.2.0",
]
@@ -3996,6 +4145,18 @@ dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "rustls"
version = "0.21.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e"
dependencies = [
"log",
"ring",
"rustls-webpki 0.101.7",
"sct",
]
[[package]]
name = "rustls"
version = "0.23.15"
@@ -4005,7 +4166,7 @@ dependencies = [
"once_cell",
"ring",
"rustls-pki-types",
"rustls-webpki",
"rustls-webpki 0.102.8",
"subtle",
"zeroize",
]
@@ -4025,6 +4186,16 @@ version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b"
[[package]]
name = "rustls-webpki"
version = "0.101.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
dependencies = [
"ring",
"untrusted",
]
[[package]]
name = "rustls-webpki"
version = "0.102.8"
@@ -4099,6 +4270,16 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "sct"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414"
dependencies = [
"ring",
"untrusted",
]
[[package]]
name = "security-framework"
version = "2.11.1"
@@ -4665,7 +4846,7 @@ dependencies = [
"glob",
"gtk",
"heck 0.5.0",
"http",
"http 1.1.0",
"http-range",
"image",
"jni",
@@ -4909,7 +5090,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c752aee1b00ec3c4d4f440095995d9bd2c640b478f2067d1fba388900b82eb96"
dependencies = [
"data-url",
"http",
"http 1.1.0",
"regex",
"reqwest",
"schemars",
@@ -5036,7 +5217,7 @@ dependencies = [
"dirs 6.0.0",
"flate2",
"futures-util",
"http",
"http 1.1.0",
"infer",
"minisign-verify",
"osakit",
@@ -5064,7 +5245,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14055b796521e0facf6582256dea9322453595917851082610c557293862c966"
dependencies = [
"futures-util",
"http",
"http 1.1.0",
"log",
"rand 0.8.5",
"serde",
@@ -5073,7 +5254,7 @@ dependencies = [
"tauri-plugin",
"thiserror 2.0.6",
"tokio",
"tokio-tungstenite",
"tokio-tungstenite 0.24.0",
]
[[package]]
@@ -5084,7 +5265,7 @@ checksum = "cce18d43f80d4aba3aa8a0c953bbe835f3d0f2370aca75e8dbb14bd4bab27958"
dependencies = [
"dpi",
"gtk",
"http",
"http 1.1.0",
"jni",
"raw-window-handle",
"serde",
@@ -5102,7 +5283,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f442a38863e10129ffe2cec7bd09c2dcf8a098a3a27801a476a304d5bb991d2"
dependencies = [
"gtk",
"http",
"http 1.1.0",
"jni",
"log",
"objc2",
@@ -5133,7 +5314,7 @@ dependencies = [
"dunce",
"glob",
"html5ever",
"http",
"http 1.1.0",
"infer",
"json-patch",
"kuchikiki",
@@ -5313,6 +5494,7 @@ dependencies = [
"bytes",
"libc",
"mio 1.0.2",
"parking_lot",
"pin-project-lite",
"signal-hook-registry",
"socket2 0.5.7",
@@ -5342,17 +5524,42 @@ dependencies = [
"tokio",
]
[[package]]
name = "tokio-rustls"
version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
dependencies = [
"rustls 0.21.12",
"tokio",
]
[[package]]
name = "tokio-rustls"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4"
dependencies = [
"rustls",
"rustls 0.23.15",
"rustls-pki-types",
"tokio",
]
[[package]]
name = "tokio-tungstenite"
version = "0.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c"
dependencies = [
"futures-util",
"log",
"rustls 0.21.12",
"tokio",
"tokio-rustls 0.24.1",
"tungstenite 0.20.1",
"webpki-roots 0.25.4",
]
[[package]]
name = "tokio-tungstenite"
version = "0.24.0"
@@ -5361,12 +5568,12 @@ checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9"
dependencies = [
"futures-util",
"log",
"rustls",
"rustls 0.23.15",
"rustls-pki-types",
"tokio",
"tokio-rustls",
"tungstenite",
"webpki-roots",
"tokio-rustls 0.26.0",
"tungstenite 0.24.0",
"webpki-roots 0.26.6",
]
[[package]]
@@ -5543,6 +5750,26 @@ version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]]
name = "tungstenite"
version = "0.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9"
dependencies = [
"byteorder",
"bytes",
"data-encoding",
"http 0.2.12",
"httparse",
"log",
"rand 0.8.5",
"rustls 0.21.12",
"sha1",
"thiserror 1.0.64",
"url",
"utf-8",
]
[[package]]
name = "tungstenite"
version = "0.24.0"
@@ -5552,11 +5779,11 @@ dependencies = [
"byteorder",
"bytes",
"data-encoding",
"http",
"http 1.1.0",
"httparse",
"log",
"rand 0.8.5",
"rustls",
"rustls 0.23.15",
"rustls-pki-types",
"sha1",
"thiserror 1.0.64",
@@ -5690,6 +5917,12 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "uuid"
version = "1.10.0"
@@ -5969,6 +6202,12 @@ dependencies = [
"system-deps",
]
[[package]]
name = "webpki-roots"
version = "0.25.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
[[package]]
name = "webpki-roots"
version = "0.26.6"
@@ -6472,7 +6711,7 @@ dependencies = [
"gdkx11",
"gtk",
"html5ever",
"http",
"http 1.1.0",
"javascriptcore-rs",
"jni",
"kuchikiki",

View File

@@ -39,12 +39,14 @@ tauri-plugin-updater = "2"
tauri-plugin-process = "2"
tauri-plugin-drag = "2"
tokio-native-tls = "0.3" # For wss connections
tokio = { version = "1", features = ["full"] }
tokio-tungstenite = { version = "0.20", features = ["rustls-tls-webpki-roots"] }
hyper = { version = "0.14", features = ["client"] }
reqwest = "0.12.12"
futures = "0.3.31"
ordered-float = { version = "4.6.0", default-features = false }
lazy_static = "1.5.0"
log = "0.4.22"
tokio = "1.40.0"
once_cell = "1.20.2"
notify = "5.0"
async-trait = "0.1.82"
@@ -55,6 +57,13 @@ plist = "1.7"
base64 = "0.13"
walkdir = "2"
fuzzy_prefix_search = "0.2"
log = "0.4"
futures-util = "0.3.31"
url = "2.5.2"
http = "1.1.0"
tungstenite = "0.24.0"
env_logger = "0.11.5"
[target."cfg(target_os = \"macos\")".dependencies]
tauri-nspanel = { git = "https://github.com/ahkohd/tauri-nspanel", branch = "v2" }

View File

@@ -31,6 +31,7 @@
"core:window:allow-set-size",
"core:window:allow-get-all-windows",
"core:window:allow-set-focus",
"core:window:allow-set-always-on-top",
"core:app:allow-set-app-theme",
"shell:default",
"http:default",

View File

@@ -52,7 +52,9 @@ struct Payload {
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
let mut ctx = tauri::generate_context!();
// Initialize logger
env_logger::init();
let mut app_builder = tauri::Builder::default();
#[cfg(desktop)]
@@ -63,7 +65,8 @@ pub fn run() {
}));
}
app_builder = app_builder.plugin(tauri_plugin_http::init())
app_builder = app_builder
.plugin(tauri_plugin_http::init())
.plugin(tauri_plugin_shell::init())
.plugin(tauri_plugin_autostart::init(
MacosLauncher::AppleScript,
@@ -102,12 +105,15 @@ pub fn run() {
// server::get_coco_servers_health_info,
// server::get_user_profiles,
// server::get_coco_server_datasources,
// server::get_coco_server_connectors
// server::get_coco_server_connectors,
server::websocket::connect_to_server,
server::websocket::disconnect,
])
.setup(|app| {
let registry = SearchSourceRegistry::default();
app.manage(registry); // Store registry in Tauri's app state
app.manage(server::websocket::WebSocketManager::default());
// Get app handle
let app_handle = app.handle().clone();

View File

@@ -17,3 +17,4 @@ pub mod datasource;
pub mod http_client;
pub mod profile;
pub mod search;
pub mod websocket;

View File

@@ -0,0 +1,175 @@
use crate::server::servers::{get_server_by_id, get_server_token};
use futures_util::{SinkExt, StreamExt};
use http::{HeaderMap, HeaderName, HeaderValue};
use std::sync::Arc;
use tauri::Emitter;
use tokio::net::TcpStream;
use tokio::sync::{mpsc, Mutex};
use tokio_tungstenite::tungstenite::client::IntoClientRequest;
use tokio_tungstenite::tungstenite::Error;
use tokio_tungstenite::{connect_async, tungstenite::protocol::Message, MaybeTlsStream, WebSocketStream};
use tungstenite::handshake::client::generate_key;
#[derive(Default)]
pub struct WebSocketManager {
ws_connection: Arc<Mutex<Option<WebSocketStream<MaybeTlsStream<TcpStream>>>>>,
cancel_tx: Arc<Mutex<Option<mpsc::Sender<()>>>>,
}
// Function to convert the HTTP endpoint to WebSocket endpoint
fn convert_to_websocket(endpoint: &str) -> Result<String, String> {
let url = url::Url::parse(endpoint).map_err(|e| format!("Invalid URL: {}", e))?;
// Determine WebSocket protocol based on the scheme
let ws_protocol = if url.scheme() == "https" { "wss://" } else { "ws://" };
// Extract host and port (if present)
let host = url.host_str().ok_or_else(|| "No host found in URL")?;
let port = url.port_or_known_default().unwrap_or(if url.scheme() == "https" { 443 } else { 80 });
// Build WebSocket URL, include the port if not the default
let ws_endpoint = if port == 80 || port == 443 {
format!("{}{}{}", ws_protocol, host, "/ws")
} else {
format!("{}{}:{}/ws", ws_protocol, host, port)
};
Ok(ws_endpoint)
}
// Function to build a HeaderMap from a vector of key-value pairs
fn build_header_map(headers: Vec<(String, String)>) -> Result<HeaderMap, String> {
let mut header_map = HeaderMap::new();
for (key, value) in headers {
let header_name = HeaderName::from_bytes(key.as_bytes())
.map_err(|e| format!("Invalid header name: {}", e))?;
let header_value = HeaderValue::from_str(&value)
.map_err(|e| format!("Invalid header value: {}", e))?;
header_map.insert(header_name, header_value);
}
Ok(header_map)
}
#[tauri::command]
pub async fn connect_to_server(
id: String,
state: tauri::State<'_, WebSocketManager>,
app_handle: tauri::AppHandle,
) -> Result<(), String> {
dbg!("Connecting to server",id.as_str());
// Disconnect any existing connection first
disconnect(state.clone()).await?;
dbg!("Disconnected from previous server",id.as_str());
// Retrieve server details
let server = get_server_by_id(id.as_str())
.ok_or_else(|| format!("Server with ID {} not found", id))?;
let mut endpoint = convert_to_websocket(server.endpoint.as_str())?;
dbg!("Server endpoint",endpoint.as_str());
// Retrieve the token for the server (token is optional)
let token = get_server_token(id.as_str()).map(|t| t.access_token.clone());
dbg!("Server token",token.as_ref().unwrap_or(&"".to_string()).as_str());
// Create the WebSocket request
let mut request = tokio_tungstenite::tungstenite::client::IntoClientRequest::into_client_request(
&endpoint
).map_err(|e| format!("Failed to create WebSocket request: {}", e))?;
dbg!("WebSocket request");
// Add necessary headers
request.headers_mut().insert("Connection", "Upgrade".parse().unwrap());
request.headers_mut().insert("Upgrade", "websocket".parse().unwrap());
request.headers_mut().insert("Sec-WebSocket-Version", "13".parse().unwrap());
request.headers_mut().insert(
"Sec-WebSocket-Key",
generate_key().parse().unwrap(),
);
dbg!("WebSocket headers",request.headers().iter().map(|(k, v)| format!("{}: {}", k.as_str(), v.to_str().unwrap())).collect::<Vec<String>>().join("\n"));
// If a token exists, add it to the headers
if let Some(token) = token {
request.headers_mut().insert("X-API-TOKEN", token.parse().unwrap());
}
dbg!("WebSocket headers with token",request.headers().iter().map(|(k, v)| format!("{}: {}", k.as_str(), v.to_str().unwrap())).collect::<Vec<String>>().join("\n"));
// Establish the WebSocket connection
dbg!(&request);
let (mut ws_remote, _) = connect_async(request).await
.map_err(|e| {
dbg!("WebSocket connection error",&e);
match e {
Error::ConnectionClosed => "WebSocket connection was closed".to_string(),
Error::Protocol(protocol_error) => format!("Protocol error: {}", protocol_error),
Error::Utf8 => "UTF-8 error in WebSocket data".to_string(),
_ => format!("Unknown error: {:?}", e),
}
})?;
dbg!("Connected to server1234",id.as_str());
// Create cancellation channel
let (cancel_tx, mut cancel_rx) = mpsc::channel(1);
dbg!("try to lock Connected to server",id.as_str());
// Store connection and cancellation sender
*state.ws_connection.lock().await = Some(ws_remote);
*state.cancel_tx.lock().await = Some(cancel_tx);
dbg!("locked Connected to server",id.as_str());
// Spawn listener task with cancellation
let app_handle_clone = app_handle.clone();
let connection_clone = state.ws_connection.clone();
tokio::spawn(async move {
let mut connection = connection_clone.lock().await;
if let Some(ws) = connection.as_mut() {
loop {
dbg!("try to select Connected to server",id.as_str());
tokio::select! {
msg = ws.next() => {
match msg {
Some(Ok(Message::Text(text))) => {
let _ = app_handle_clone.emit("ws-message", text);
},
Some(Err(_)) | None => break,
_ => continue,
}
}
_ = cancel_rx.recv() => {
break;
}
}
}
}
});
dbg!("END Connected to server");
Ok(())
}
#[tauri::command]
pub async fn disconnect(state: tauri::State<'_, WebSocketManager>) -> Result<(), String> {
// Send cancellation signal
if let Some(cancel_tx) = state.cancel_tx.lock().await.take() {
let _ = cancel_tx.send(()).await;
}
// Close connection
let mut connection = state.ws_connection.lock().await;
if let Some(mut ws) = connection.take() {
let _ = ws.close(None).await;
}
Ok(())
}

View File

@@ -23,7 +23,6 @@
"maximizable": false,
"skipTaskbar": true,
"resizable": false,
"alwaysOnTop": true,
"acceptFirstMouse": true,
"shadow": true,
"transparent": true,