-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfinder.dart
103 lines (89 loc) · 3.19 KB
/
finder.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:upnp/upnp.dart';
import 'package:mdmt2_config/src/upnp/terminal_info.dart';
part 'package:mdmt2_config/src/blocs/finder.dart';
class Finder extends _BLoC {
static const ST = 'urn:schemas-upnp-org:service:mdmTerminal2';
static const searchInterval = Duration(seconds: 15);
static const autoResendInterval = Duration(seconds: 5);
// _search может упасть с эксепшеном который нельзя отловить.
// Если долго нет результата просто остановим поиск
static const mayBeDeadInterval = Duration(seconds: 30);
Timer _periodicResendTimer, _periodicSearchTimer, _mayBeDead;
StreamSubscription _subscribe;
final _discoverer = DeviceDiscoverer();
// final _terminals = <TerminalInfo>[
// TerminalInfo.direct(
// '1111', '127.0.0.1', 1111, '1', 100, (DateTime.now().millisecondsSinceEpoch / 1000).round() + 1000),
// TerminalInfo.direct(
// '2222', '127.0.0.2', 2222, '2', 200, (DateTime.now().millisecondsSinceEpoch / 1000).round() - 2000),
// TerminalInfo.direct(
// '3333', '127.0.0.3', 3333, '3', 300, (DateTime.now().millisecondsSinceEpoch / 1000).round() - 500),
// ];
final _terminals = <TerminalInfo>[];
void _startInput() async {
_work = true;
_subscribe = _discoverer.clients.listen((event) {
_startMayBeDead();
final timestamp = DateTime.now();
event.getDevice().then((value) {
final info = TerminalInfo(event, value, timestamp: timestamp);
if (info != null) _newTerminalInfo(info);
}).catchError((e) => debugPrint('*** getDevice error: $e'));
});
try {
await _discoverer.start();
} catch (e) {
stop(error: e);
return;
}
_startMayBeDead();
_search();
_periodicSearchTimer = Timer.periodic(searchInterval, (_) => _search());
_startPeriodicSend();
}
void _startPeriodicSend() => _periodicResendTimer = Timer.periodic(autoResendInterval, (_) => send());
void _startMayBeDead() {
_mayBeDead?.cancel();
_mayBeDead = Timer(mayBeDeadInterval, stop);
}
void _newTerminalInfo(TerminalInfo info) {
//debugPrint('New info: $info');
bool resend = true;
final int index = _terminals.indexOf(info);
if (index > -1) {
resend = _terminals[index].upgrade(info);
} else {
_terminals.add(info);
}
if (resend) {
_periodicResendTimer?.cancel();
send();
_startPeriodicSend();
}
}
void _stopInput() {
_work = false;
_periodicResendTimer?.cancel();
_periodicSearchTimer?.cancel();
_mayBeDead?.cancel();
_subscribe?.cancel();
try {
_discoverer.stop();
} catch (e) {
debugPrint('*** discoverer.stop: $e');
}
}
void _sendDataOutput() =>
__outputStream.add(_sort ? (_terminals.sublist(0)..sort((a, b) => b.timestampSec - a.timestampSec)) : _terminals);
_search() {
// FIXME Unhandled Exception: SocketException: Send failed (OS Error: Network is unreachable, errno = 101), address = 0.0.0.0, port = 0
// не отловить :(
_discoverer.search(ST);
}
void dispose() {
_stopInput();
super.dispose();
}
}