@@ -8,8 +8,9 @@ use futures_util::{future, pin_mut, SinkExt, StreamExt};
88use json:: JsonValue ;
99use log:: { error, info} ;
1010use std:: sync:: atomic:: { AtomicBool , Ordering } ;
11- use std:: sync:: Arc ;
11+ use std:: sync:: { Arc , Mutex } ;
1212use std:: time;
13+ use std:: time:: Duration ;
1314use tokio_tungstenite:: { connect_async, tungstenite:: protocol:: Message } ;
1415
1516const JSON_MEETING_UPDATE : & str = "meetingUpdate" ;
@@ -23,6 +24,7 @@ const JSON_IS_BACKGROUND_BLURRED: &str = "isBackgroundBlurred";
2324const JSON_IS_SHARING : & str = "isSharing" ;
2425const JSON_HAS_UNREAD_MESSAGES : & str = "hasUnreadMessages" ;
2526const JSON_TOKEN_REFRESH : & str = "tokenRefresh" ;
27+
2628pub struct TeamsAPI {
2729 pub teams_states : Arc < TeamsStates > ,
2830 pub url : String ,
@@ -56,7 +58,7 @@ impl TeamsAPI {
5658
5759 pub async fn start_listening (
5860 & self ,
59- listener : Arc < Box < dyn Listener > > ,
61+ listener : Arc < Mutex < Box < dyn Listener > > > ,
6062 is_running : Arc < AtomicBool > ,
6163 toggle_mute : Arc < AtomicBool > ,
6264 ) -> anyhow:: Result < ( ) > {
@@ -72,16 +74,17 @@ impl TeamsAPI {
7274 let data = & message. unwrap ( ) . into_data ( ) ;
7375 let json = String :: from_utf8_lossy ( data) ;
7476 info ! ( "{}" , json) ;
75- let parse_result = parse_data (
77+
78+ let parse_result = parse_data_and_notify_listener (
7679 & json,
7780 listener. clone ( ) ,
7881 self . teams_states . clone ( ) ,
7982 force_update. clone ( ) ,
8083 )
81- . await ;
84+ . await ;
8285
8386 if parse_result. is_err ( ) {
84- error ! ( "{}" , parse_result. unwrap_err( ) )
87+ error ! ( "Unable to parse or notify listener, abandoning: {}" , parse_result. unwrap_err( ) ) ;
8588 }
8689 }
8790 } )
@@ -127,9 +130,9 @@ async fn update_value(
127130 teams_state_value. swap ( new_value, Ordering :: Relaxed ) != new_value
128131}
129132
130- async fn parse_data (
133+ async fn parse_data_and_notify_listener (
131134 json : & str ,
132- listener : Arc < Box < dyn Listener > > ,
135+ listener : Arc < Mutex < Box < dyn Listener > > > ,
133136 teams_states : Arc < TeamsStates > ,
134137 force_update : Arc < AtomicBool > ,
135138) -> anyhow:: Result < ( ) > {
@@ -148,17 +151,32 @@ async fn parse_data(
148151 & answer,
149152 JSON_IS_BACKGROUND_BLURRED ,
150153 )
151- . await ;
154+ . await ;
152155 has_changed |= update_value ( & teams_states. is_sharing , & answer, JSON_IS_SHARING ) . await ;
153156 has_changed |= update_value (
154157 & teams_states. has_unread_messages ,
155158 & answer,
156159 JSON_HAS_UNREAD_MESSAGES ,
157160 )
158- . await ;
161+ . await ;
159162
160163 if force_update. swap ( false , Ordering :: Relaxed ) || has_changed {
161- listener. notify_changed ( & teams_states) . await ?;
164+ // Issue!: This will only run once regardless of MAX_RETRIES
165+ // for some reason after a reconnect the notify_changed will get a pass no matter what
166+ const MAX_RETRIES : i32 = 3 ;
167+ for i in 1 ..MAX_RETRIES {
168+ let result = listener. lock ( ) . unwrap ( ) . notify_changed ( & teams_states) . await ;
169+
170+ if result. is_ok ( ) || ( i == MAX_RETRIES ) {
171+ result?
172+ }
173+ // we will try to reconnect if the connection failed
174+ else if i < MAX_RETRIES {
175+ error ! ( "{}: Reconnecting and retrying..." , result. unwrap_err( ) ) ;
176+ tokio:: time:: sleep ( Duration :: from_secs ( 1 ) ) . await ;
177+ listener. lock ( ) . unwrap ( ) . reconnect ( ) ;
178+ }
179+ }
162180 }
163181 } else if answer. has_key ( JSON_TOKEN_REFRESH ) && !answer[ JSON_TOKEN_REFRESH ] . is_empty ( ) {
164182 change_teams_configuration (
0 commit comments