next_web_websocket/core/
router.rs1use std::{net::SocketAddr, sync::Arc};
2
3use axum::{
4 extract::{ConnectInfo, State, WebSocketUpgrade},
5 http::Uri,
6 response::IntoResponse,
7 routing::any,
8 Router,
9};
10use next_web_core::{core::router::ApplyRouter, ApplicationContext};
11use rudi_dev::SingleOwner;
12
13use super::{
14 handle_socket::handle_socket, handler::WebSocketHandler, ws_context::WebSocketContext,
15};
16
17#[SingleOwner(binds = [Self::into_router])]
18pub(crate) struct WSRouter;
19
20impl WSRouter {
21 fn into_router(self) -> Box<dyn ApplyRouter> {
22 Box::new(self)
23 }
24}
25
26impl ApplyRouter for WSRouter {
27 fn router(&self, ctx: &mut ApplicationContext) -> axum::Router {
28 let mut router = Router::new();
29 let mut context = ctx.resolve::<WebSocketContext>();
30 let handlers = ctx.resolve_by_type::<Arc<dyn WebSocketHandler>>();
31
32 for item in handlers.iter() {
33 for path in item.paths() {
34 router = router.route(path, any(ws_handler));
35 context.add_handler(path, item.clone());
36 }
37 }
38 router.with_state(Arc::new(context))
39 }
40}
41
42async fn ws_handler(
48 ws: WebSocketUpgrade,
49 ConnectInfo(addr): ConnectInfo<SocketAddr>,
50 State(ctx): State<Arc<WebSocketContext>>,
51 uri: Uri,
52) -> impl IntoResponse {
53 let properties = ctx.properties();
56 let path = uri.path().to_string();
57 ws.max_message_size(properties.max_msg_size().unwrap_or(64 << 20))
58 .max_write_buffer_size(properties.max_write_buffer_size().unwrap_or(usize::MAX))
59 .on_upgrade(move |socket| handle_socket(socket, ctx, addr, path))
60}