@@ -9,7 +9,7 @@ import 'package:elastic_dashboard/services/log.dart';
9
9
class DSInteropClient {
10
10
final String serverBaseAddress = '127.0.0.1' ;
11
11
bool _serverConnectionActive = false ;
12
- bool _dbModeConnectionActive = false ;
12
+ bool _dbModeServerRunning = false ;
13
13
14
14
Function ()? onConnect;
15
15
Function ()? onDisconnect;
@@ -20,6 +20,8 @@ class DSInteropClient {
20
20
Socket ? _socket;
21
21
ServerSocket ? _dbModeServer;
22
22
23
+ final List <Socket > _connectedSockets = [];
24
+
23
25
List <int > _tcpBuffer = [];
24
26
25
27
String ? _lastAnnouncedIP;
@@ -28,21 +30,34 @@ class DSInteropClient {
28
30
String ? get lastAnnouncedIP => _lastAnnouncedIP;
29
31
bool get driverStationDocked => _driverStationDocked;
30
32
33
+ bool _attemptServerStart = true ;
34
+
35
+ DateTime serverStopTime = DateTime .now ();
36
+
31
37
DSInteropClient ({
32
38
this .onNewIPAnnounced,
33
39
this .onDriverStationDockChanged,
34
40
this .onConnect,
35
41
this .onDisconnect,
36
42
}) {
37
- _connect ();
43
+ _tcpSocketConnect ();
38
44
}
39
45
40
- void _connect () {
41
- if (_serverConnectionActive) {
42
- return ;
46
+ void startDBModeServer () {
47
+ // For some reason if the server is quickly stopped then started there's a 5 second delay
48
+ // The workaround is to use the cached value of the docked state
49
+ if (DateTime .now ().microsecondsSinceEpoch -
50
+ serverStopTime.microsecondsSinceEpoch <=
51
+ 5 * 1e6 ) {
52
+ onDriverStationDockChanged? .call (_driverStationDocked);
43
53
}
44
- _tcpSocketConnect ();
45
- _dbModeServerConnect ();
54
+ _attemptServerStart = true ;
55
+ _startDBModeServer ();
56
+ }
57
+
58
+ void stopDBModeServer () {
59
+ serverStopTime = DateTime .now ();
60
+ _dbModeServerClose (false );
46
61
}
47
62
48
63
void _tcpSocketConnect () async {
@@ -74,30 +89,36 @@ class DSInteropClient {
74
89
);
75
90
}
76
91
77
- void _dbModeServerConnect () async {
78
- if (_dbModeConnectionActive ) {
92
+ Future < void > _startDBModeServer () async {
93
+ if (_dbModeServerRunning || ! _attemptServerStart ) {
79
94
return ;
80
95
}
81
96
try {
82
97
_dbModeServer = await ServerSocket .bind (serverBaseAddress, 1741 );
83
98
} catch (e) {
84
- logger.info (
85
- 'Failed to start TCP server on port 1741, attempting to reconnect in 5 seconds' );
86
- Future .delayed (const Duration (seconds: 5 ), _dbModeServerConnect);
99
+ if (_attemptServerStart) {
100
+ logger.info (
101
+ 'Failed to start TCP server on port 1741, attempting to restart in 5 seconds' );
102
+ Future .delayed (const Duration (seconds: 5 ), _startDBModeServer);
103
+ } else {
104
+ logger.info ('Failed to start TCP server on port 1741' );
105
+ }
87
106
return ;
88
107
}
89
108
109
+ _attemptServerStart = false ;
110
+ _dbModeServerRunning = true ;
111
+
90
112
_dbModeServer! .listen (
91
113
(socket) {
92
114
logger.info ('Received connection from Driver Station on TCP port 1741' );
115
+ _connectedSockets.add (socket);
93
116
socket.listen (
94
117
(data) {
95
- if (! _dbModeConnectionActive) {
96
- _dbModeConnectionActive = true ;
97
- }
98
118
_dbModeServerOnMessage (data);
99
119
},
100
120
onDone: () {
121
+ _connectedSockets.remove (socket);
101
122
logger.info ('Lost connection from Driver Station on TCP port 1741' );
102
123
},
103
124
);
@@ -174,39 +195,53 @@ class DSInteropClient {
174
195
}
175
196
}
176
197
177
- void _socketClose () {
198
+ void _socketClose () async {
178
199
if (! _serverConnectionActive) {
179
200
return ;
180
201
}
181
202
182
- _socket? .close ();
203
+ await _socket? .close ();
183
204
_socket = null ;
184
205
185
206
_serverConnectionActive = false ;
186
207
187
- _driverStationDocked = false ;
188
- onDriverStationDockChanged? .call (false );
189
208
onDisconnect? .call ();
190
209
191
210
logger.info (
192
211
'Driver Station connection on TCP port 1742 closed, attempting to reconnect in 5 seconds.' );
193
212
194
- Future .delayed (const Duration (seconds: 5 ), _connect );
213
+ Future .delayed (const Duration (seconds: 5 ), _tcpSocketConnect );
195
214
}
196
215
197
- void _dbModeServerClose () {
198
- if (! _dbModeConnectionActive ) {
216
+ void _dbModeServerClose ([ bool reconnect = true ]) async {
217
+ if (! _dbModeServerRunning ) {
199
218
return ;
200
219
}
201
220
202
- _dbModeServer? .close ();
221
+ _dbModeServerRunning = false ;
222
+
223
+ // Cloning the list because closing each socket changes the size of the list
224
+ for (Socket socket in _connectedSockets.toList ()) {
225
+ await socket.close ();
226
+ socket.destroy ();
227
+ }
228
+
229
+ await _dbModeServer? .close ();
203
230
_dbModeServer = null ;
204
231
205
- _dbModeConnectionActive = false ;
232
+ onDriverStationDockChanged ? . call ( false ) ;
206
233
207
- logger.info (
208
- 'Driver Station TCP Server on Port 1741 closed, attempting to reconnect in 5 seconds.' );
234
+ _tcpBuffer.clear ();
235
+
236
+ _attemptServerStart = reconnect;
209
237
210
- Future .delayed (const Duration (seconds: 5 ), _dbModeServerConnect);
238
+ if (reconnect) {
239
+ logger.info (
240
+ 'Driver Station TCP Server on Port 1741 closed, attempting to reconnect in 5 seconds.' );
241
+
242
+ Future .delayed (const Duration (seconds: 5 ), _startDBModeServer);
243
+ } else {
244
+ logger.info ('Driver Station TCP Server on Port 1741 closed' );
245
+ }
211
246
}
212
247
}
0 commit comments