11use crate :: server:: Server ;
22use lan_mouse_ipc:: { ClientHandle , DEFAULT_PORT } ;
33use lan_mouse_proto:: { ProtoEvent , MAX_EVENT_SIZE } ;
4+ use local_channel:: mpsc:: { channel, Receiver , Sender } ;
45use std:: {
56 collections:: { HashMap , HashSet } ,
67 io,
@@ -67,17 +68,26 @@ pub(crate) struct LanMouseConnection {
6768 server : Server ,
6869 conns : Rc < Mutex < HashMap < SocketAddr , Arc < dyn Conn + Send + Sync > > > > ,
6970 connecting : Rc < Mutex < HashSet < ClientHandle > > > ,
71+ recv_rx : Receiver < ( ClientHandle , ProtoEvent ) > ,
72+ recv_tx : Sender < ( ClientHandle , ProtoEvent ) > ,
7073}
7174
7275impl LanMouseConnection {
7376 pub ( crate ) fn new ( server : Server ) -> Self {
77+ let ( recv_tx, recv_rx) = channel ( ) ;
7478 Self {
7579 server,
7680 conns : Default :: default ( ) ,
7781 connecting : Default :: default ( ) ,
82+ recv_rx,
83+ recv_tx,
7884 }
7985 }
8086
87+ pub ( crate ) async fn recv ( & mut self ) -> ( ClientHandle , ProtoEvent ) {
88+ self . recv_rx . recv ( ) . await . expect ( "channel closed" )
89+ }
90+
8191 pub ( crate ) async fn send (
8292 & self ,
8393 event : ProtoEvent ,
@@ -103,68 +113,105 @@ impl LanMouseConnection {
103113 }
104114
105115 // check if we are already trying to connect
106- {
107- let mut connecting = self . connecting . lock ( ) . await ;
108- if connecting. contains ( & handle) {
109- return Err ( LanMouseConnectionError :: NotConnected ) ;
110- } else {
111- connecting. insert ( handle) ;
112- }
116+ let mut connecting = self . connecting . lock ( ) . await ;
117+ if !connecting. contains ( & handle) {
118+ connecting. insert ( handle) ;
119+ // connect in the background
120+ spawn_local ( connect_to_handle (
121+ self . server . clone ( ) ,
122+ handle,
123+ self . conns . clone ( ) ,
124+ self . connecting . clone ( ) ,
125+ self . recv_tx . clone ( ) ,
126+ ) ) ;
113127 }
114- let server = self . server . clone ( ) ;
115- let conns = self . conns . clone ( ) ;
116- let connecting = self . connecting . clone ( ) ;
128+ Err ( LanMouseConnectionError :: NotConnected )
129+ }
130+ }
117131
118- // connect in the background
119- spawn_local ( async move {
120- // sending did not work, figure out active conn.
121- if let Some ( addrs) = server. get_ips ( handle) {
122- let port = server. get_port ( handle) . unwrap_or ( DEFAULT_PORT ) ;
123- let addrs = addrs
124- . into_iter ( )
125- . map ( |a| SocketAddr :: new ( a, port) )
126- . collect :: < Vec < _ > > ( ) ;
127- log:: info!( "client ({handle}) connecting ... (ips: {addrs:?})" ) ;
128- let res = connect_any ( & addrs) . await ;
129- let ( conn, addr) = match res {
130- Ok ( c) => c,
131- Err ( e) => {
132- connecting. lock ( ) . await . remove ( & handle) ;
133- return Err ( e) ;
134- }
135- } ;
136- log:: info!( "client ({handle}) connected @ {addr}" ) ;
137- server. set_active_addr ( handle, Some ( addr) ) ;
138- conns. lock ( ) . await . insert ( addr, conn. clone ( ) ) ;
132+ async fn connect_to_handle (
133+ server : Server ,
134+ handle : ClientHandle ,
135+ conns : Rc < Mutex < HashMap < SocketAddr , Arc < dyn Conn + Send + Sync > > > > ,
136+ connecting : Rc < Mutex < HashSet < ClientHandle > > > ,
137+ tx : Sender < ( ClientHandle , ProtoEvent ) > ,
138+ ) -> Result < ( ) , LanMouseConnectionError > {
139+ // sending did not work, figure out active conn.
140+ if let Some ( addrs) = server. get_ips ( handle) {
141+ let port = server. get_port ( handle) . unwrap_or ( DEFAULT_PORT ) ;
142+ let addrs = addrs
143+ . into_iter ( )
144+ . map ( |a| SocketAddr :: new ( a, port) )
145+ . collect :: < Vec < _ > > ( ) ;
146+ log:: info!( "client ({handle}) connecting ... (ips: {addrs:?})" ) ;
147+ let res = connect_any ( & addrs) . await ;
148+ let ( conn, addr) = match res {
149+ Ok ( c) => c,
150+ Err ( e) => {
139151 connecting. lock ( ) . await . remove ( & handle) ;
140- spawn_local ( async move {
141- loop {
142- let ( buf, len) = ProtoEvent :: Ping . into ( ) ;
143- if let Err ( e) = conn. send ( & buf[ ..len] ) . await {
144- log:: warn!( "client ({handle}) @ {addr} connection closed: {e}" ) ;
145- conns. lock ( ) . await . remove ( & addr) ;
146- server. set_active_addr ( handle, None ) ;
147- let active: Vec < SocketAddr > =
148- conns. lock ( ) . await . keys ( ) . copied ( ) . collect ( ) ;
149- log:: info!( "active connections: {active:?}" ) ;
150- break ;
151- }
152- tokio:: time:: sleep ( Duration :: from_millis ( 500 ) ) . await ;
153- let mut buf = [ 0u8 ; MAX_EVENT_SIZE ] ;
154- if let Err ( e) = conn. recv ( & mut buf) . await {
155- log:: warn!( "recv(): client ({handle}) @ {addr} connection closed: {e}" ) ;
156- conns. lock ( ) . await . remove ( & addr) ;
157- server. set_active_addr ( handle, None ) ;
158- let active: Vec < SocketAddr > =
159- conns. lock ( ) . await . keys ( ) . copied ( ) . collect ( ) ;
160- log:: info!( "active connections: {active:?}" ) ;
161- break ;
162- }
163- }
164- } ) ;
152+ return Err ( e) ;
165153 }
166- Result :: < ( ) , LanMouseConnectionError > :: Ok ( ( ) )
167- } ) ;
168- Err ( LanMouseConnectionError :: NotConnected )
154+ } ;
155+ log:: info!( "client ({handle}) connected @ {addr}" ) ;
156+ server. set_active_addr ( handle, Some ( addr) ) ;
157+ conns. lock ( ) . await . insert ( addr, conn. clone ( ) ) ;
158+ connecting. lock ( ) . await . remove ( & handle) ;
159+
160+ // poll connection for active
161+ spawn_local ( ping_pong (
162+ server. clone ( ) ,
163+ handle,
164+ addr,
165+ conn. clone ( ) ,
166+ conns. clone ( ) ,
167+ ) ) ;
168+
169+ // receiver
170+ spawn_local ( receive_loop ( handle, conn, tx) ) ;
171+ return Ok ( ( ) ) ;
172+ }
173+ Err ( LanMouseConnectionError :: NotConnected )
174+ }
175+
176+ async fn ping_pong (
177+ server : Server ,
178+ handle : ClientHandle ,
179+ addr : SocketAddr ,
180+ conn : Arc < dyn Conn + Send + Sync > ,
181+ conns : Rc < Mutex < HashMap < SocketAddr , Arc < dyn Conn + Send + Sync > > > > ,
182+ ) {
183+ loop {
184+ let ( buf, len) = ProtoEvent :: Ping . into ( ) ;
185+ if let Err ( e) = conn. send ( & buf[ ..len] ) . await {
186+ log:: warn!( "client ({handle}) @ {addr} connection closed: {e}" ) ;
187+ conns. lock ( ) . await . remove ( & addr) ;
188+ server. set_active_addr ( handle, None ) ;
189+ let active: Vec < SocketAddr > = conns. lock ( ) . await . keys ( ) . copied ( ) . collect ( ) ;
190+ log:: info!( "active connections: {active:?}" ) ;
191+ break ;
192+ }
193+ tokio:: time:: sleep ( Duration :: from_millis ( 500 ) ) . await ;
194+ let mut buf = [ 0u8 ; MAX_EVENT_SIZE ] ;
195+ if let Err ( e) = conn. recv ( & mut buf) . await {
196+ log:: warn!( "recv(): client ({handle}) @ {addr} connection closed: {e}" ) ;
197+ conns. lock ( ) . await . remove ( & addr) ;
198+ server. set_active_addr ( handle, None ) ;
199+ let active: Vec < SocketAddr > = conns. lock ( ) . await . keys ( ) . copied ( ) . collect ( ) ;
200+ log:: info!( "active connections: {active:?}" ) ;
201+ break ;
202+ }
203+ }
204+ }
205+
206+ async fn receive_loop (
207+ handle : ClientHandle ,
208+ conn : Arc < dyn Conn + Send + Sync > ,
209+ tx : Sender < ( ClientHandle , ProtoEvent ) > ,
210+ ) {
211+ let mut buf = [ 0u8 ; MAX_EVENT_SIZE ] ;
212+ while let Ok ( _) = conn. recv ( & mut buf) . await {
213+ if let Ok ( event) = buf. try_into ( ) {
214+ tx. send ( ( handle, event) ) ;
215+ }
169216 }
170217}
0 commit comments