Skip to content

Commit 1e0ad0b

Browse files
committed
WIP
1 parent d39e1e6 commit 1e0ad0b

5 files changed

Lines changed: 187 additions & 135 deletions

File tree

src/libs/ws/server.rs

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ use crate::libs::utils::{get_conn_id, get_log_id};
2020
use crate::libs::ws::HyperTungsteniteUpgrader;
2121
#[cfg(any(feature = "ws", feature = "ws-wtx"))]
2222
use crate::libs::ws::TlsListener;
23-
#[cfg(all(feature = "ws-wtx", not(feature = "ws")))]
24-
use crate::libs::ws::WtxUpgrader;
23+
#[cfg(feature = "ws")]
24+
use crate::libs::ws::tungstenite::upgrader::create_ws_stream;
2525
use crate::libs::ws::{
2626
BoxedStream, ConnectionListener, TcpListener, WsClientSession, WsConnection, WsRequest,
2727
WsStream, WsUpgrader,
@@ -93,6 +93,7 @@ impl WebsocketServer {
9393
);
9494
}
9595
}
96+
9697
async fn handle_ws_handshake_and_connection(
9798
self: Arc<Self>,
9899
addr: SocketAddr,
@@ -103,26 +104,45 @@ impl WebsocketServer {
103104
let upgrader = self.upgrader.as_ref().ok_or_else(|| {
104105
eyre!("No WS backend configured; call set_upgrader() before listen()")
105106
})?;
106-
match upgrader
107-
.upgrade(stream, addr, &self.config, &cached_date)
108-
.await
109-
{
110-
Ok((ws_stream, protocol)) => {
111-
debug!(ws_server = true, ?addr, protocol = %protocol, "WsServer: upgrade succeeded, protocol received");
112-
self.post_upgrade_connection(addr, states, ws_stream, protocol)
113-
.await;
114-
Ok(())
115-
}
116-
Err(e) if e.to_string().contains("not a websocket upgrade") => {
107+
108+
// Get upgrade event receiver - H2 yields multiple events, H1 yields one
109+
let mut rx = upgrader
110+
.upgrade_stream(stream, addr, &self.config, &cached_date)
111+
.await?;
112+
113+
// Loop: spawn session task for each upgrade event
114+
while let Some(event) = rx.recv().await {
115+
let this = Arc::clone(&self);
116+
let states = Arc::clone(&states);
117+
let addr_clone = addr;
118+
119+
tokio::task::spawn_local(async move {
120+
let ws_stream = match create_ws_stream(event.on_upgrade).await {
121+
Ok(s) => s,
122+
Err(e) => {
123+
error!(ws_server = true, ?addr_clone, "on_upgrade failed: {e}");
124+
return;
125+
}
126+
};
127+
117128
debug!(
118129
ws_server = true,
119-
?addr,
120-
"Non-WebSocket HTTP request ignored"
130+
?addr_clone,
131+
protocol = %event.protocol,
132+
"WsServer: upgrade succeeded, protocol received"
121133
);
122-
Ok(())
123-
}
124-
Err(e) => Err(e),
134+
135+
this.post_upgrade_connection(addr_clone, states, ws_stream, event.protocol)
136+
.await;
137+
});
125138
}
139+
140+
debug!(
141+
ws_server = true,
142+
?addr,
143+
"Connection handler loop exited (TCP connection closed)"
144+
);
145+
Ok(())
126146
}
127147

128148
async fn post_upgrade_connection(
@@ -510,11 +530,7 @@ fn default_upgrader() -> Option<Arc<dyn WsUpgrader>> {
510530
{
511531
return Some(Arc::new(HyperTungsteniteUpgrader));
512532
}
513-
#[cfg(all(feature = "ws-wtx", not(feature = "ws")))]
514-
{
515-
return Some(Arc::new(WtxUpgrader));
516-
}
517-
#[cfg(not(any(feature = "ws", feature = "ws-wtx")))]
533+
#[cfg(not(feature = "ws"))]
518534
{
519535
None
520536
}

src/libs/ws/traits.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::net::SocketAddr;
44
use async_trait::async_trait;
55
use eyre::Result;
66
use tokio::io::{AsyncRead, AsyncWrite};
7+
use tokio::sync::mpsc;
78

89
use super::WsMessage as Message;
910
use super::WsServerConfig;
@@ -48,13 +49,23 @@ pub trait WsStream: Unpin + Send {
4849
async fn recv(&mut self) -> Option<Result<Message, StreamError>>;
4950
}
5051

52+
/// An upgrade event yielded by the upgrader.
53+
/// Contains the on_upgrade future and the negotiated protocol.
54+
pub struct UpgradeEvent {
55+
pub on_upgrade: hyper::upgrade::OnUpgrade,
56+
pub protocol: String,
57+
}
58+
5159
#[async_trait]
5260
pub trait WsUpgrader: Send + Sync {
53-
async fn upgrade(
61+
/// Returns a receiver that yields upgrade events.
62+
/// - H1: receiver yields exactly one event (single WebSocket per TCP connection)
63+
/// - H2: receiver yields multiple events (one per CONNECT request, multiplexing)
64+
async fn upgrade_stream(
5465
&self,
5566
stream: BoxedStream,
5667
addr: SocketAddr,
5768
config: &WsServerConfig,
5869
cached_date: &str,
59-
) -> Result<(Box<dyn WsStream>, String)>;
60-
}
70+
) -> Result<mpsc::Receiver<UpgradeEvent>>;
71+
}

src/libs/ws/tungstenite.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
pub mod upgrader;
2+
23
pub use upgrader::HyperTungsteniteUpgrader;
4+
pub use upgrader::create_ws_stream;

0 commit comments

Comments
 (0)