@@ -12,26 +12,27 @@ const kBroadcastDelay = Duration(seconds: 1);
12
12
13
13
class NetworkService {
14
14
final SettingsCubit settingsCubit;
15
- late final RawDatagramSocket _server;
15
+ RawDatagramSocket ? _server;
16
16
17
17
final BehaviorSubject <List <(GameServer , LanProperty ?)>> _servers =
18
18
BehaviorSubject .seeded ([]);
19
19
20
20
NetworkService (this .settingsCubit);
21
21
22
22
Future <void > init () async {
23
- if (kIsWeb) return ;
24
- _server =
25
- await RawDatagramSocket .bind (InternetAddress .anyIPv4, kBroadcastPort);
26
- _server.broadcastEnabled = true ;
23
+ if (! kIsWeb) {
24
+ _server = (await RawDatagramSocket .bind (
25
+ InternetAddress .anyIPv4, kBroadcastPort))
26
+ ..broadcastEnabled = true ;
27
+ }
27
28
_fetchServers ().listen ((event) {
28
29
_servers.add (event);
29
30
});
30
31
}
31
32
32
33
void dispose () {
33
34
if (kIsWeb) return ;
34
- _server.close ();
35
+ _server? .close ();
35
36
}
36
37
37
38
Stream <List <(GameServer , LanProperty ?)>> _fetchServers ({
@@ -56,12 +57,17 @@ class NetworkService {
56
57
});
57
58
}
58
59
59
- if (kIsWeb) return ;
60
+ final settingsStream = settingsCubit.stream.map ((event) => buildServers ());
61
+
62
+ if (kIsWeb) {
63
+ yield * settingsStream;
64
+ return ;
65
+ }
60
66
final serverStream = _server
61
- .where ((event) => event == RawSocketEvent .read)
67
+ ? .where ((event) => event == RawSocketEvent .read)
62
68
.map ((RawSocketEvent event) {
63
69
removeOld ();
64
- final datagram = _server.receive ();
70
+ final datagram = _server? .receive ();
65
71
if (datagram != null ) {
66
72
final message = String .fromCharCodes (datagram.data);
67
73
final property = LanPropertyMapper .fromJson (message);
@@ -79,8 +85,7 @@ class NetworkService {
79
85
.toList (),
80
86
);
81
87
});
82
- final settingsStream = settingsCubit.stream.map ((event) => buildServers ());
83
- yield * Rx .merge ([serverStream, settingsStream]);
88
+ yield * Rx .merge ([if (serverStream != null ) serverStream, settingsStream]);
84
89
}
85
90
86
91
(Timer , RawDatagramSocket )? _broadcast;
@@ -109,12 +114,17 @@ class NetworkService {
109
114
}
110
115
111
116
Future <GameProperty ?> fetchInfo (Uri address) async {
112
- final response = await http.get (address, headers: {
113
- HttpHeaders .contentTypeHeader: 'application/json' ,
114
- 'X-Quokka-Method' : 'info' ,
115
- });
117
+ try {
118
+ final response = await http.get (address, headers: {
119
+ HttpHeaders .contentTypeHeader: 'application/json' ,
120
+ 'X-Quokka-Method' : 'info' ,
121
+ });
122
+ if (response.statusCode != HttpStatus .ok) return null ;
116
123
117
- return GamePropertyMapper .fromJson (response.body);
124
+ return GamePropertyMapper .fromJson (response.body);
125
+ } catch (_) {
126
+ return null ;
127
+ }
118
128
}
119
129
120
130
Stream <Map <GameServer , GameProperty ?>> fetchServersWithProperties ({
@@ -135,26 +145,27 @@ class NetworkService {
135
145
}
136
146
137
147
final returned = < GameServer , GameProperty ? > {};
148
+ yield returned;
138
149
139
150
await for (final event in _servers) {
140
151
returned.removeWhere ((key, value) => ! event.any ((e) => e.$1 == key));
141
152
for (final (server, _) in event) {
142
153
returned[server] = const GameProperty ();
143
154
}
155
+ yield returned;
144
156
145
157
if (event.isEmpty) {
146
- yield returned;
147
158
continue ;
148
159
}
149
160
150
- yield * Stream . fromFutures (event. map ((e) async {
161
+ for ( final e in event) {
151
162
try {
152
163
returned[e.$1] = await fetch (e.$1, e.$2);
153
164
} catch (_) {
154
165
returned[e.$1] = null ;
155
166
}
156
- return returned;
157
- }));
167
+ yield returned;
168
+ }
158
169
}
159
170
}
160
171
}
0 commit comments