OLD | NEW |
| (Empty) |
1 // Copyright (c) 2015, the Fletch project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE.md file. | |
4 | |
5 library mdns.src.native_extension_client; | |
6 | |
7 import 'dart:async'; | |
8 import 'dart:io'; | |
9 import 'dart:isolate'; | |
10 | |
11 import 'package:mdns/mdns.dart'; | |
12 import 'package:mdns/src/lookup_resolver.dart'; | |
13 import 'package:mdns/src/packet.dart'; | |
14 | |
15 import "dart-ext:../native/mdns_extension_lib"; | |
16 | |
17 // Requests Ids. This should be aligned with the C code. | |
18 enum RequestType { | |
19 echoRequest, // 0 | |
20 lookupRequest, // 1 | |
21 } | |
22 | |
23 // Implementation of mDNS client using a native extension. | |
24 class NativeExtensionMDnsClient implements MDnsClient { | |
25 bool _starting = false; | |
26 bool _started = false; | |
27 SendPort _service; | |
28 ReceivePort _incoming; | |
29 final LookupResolver _resolver = new LookupResolver(); | |
30 | |
31 /// Start the mDNS client. | |
32 Future start() async { | |
33 if (_started && _starting) { | |
34 throw new StateError('mDNS client already started'); | |
35 } | |
36 _starting = true; | |
37 | |
38 _service = servicePort(); | |
39 _incoming = new ReceivePort(); | |
40 _incoming.listen(_handleIncoming); | |
41 | |
42 _starting = false; | |
43 _started = true; | |
44 } | |
45 | |
46 void stop() { | |
47 if (!_started) return; | |
48 if (_starting) { | |
49 throw new StateError('Cannot stop mDNS client wile it is starting'); | |
50 } | |
51 | |
52 _incoming.close(); | |
53 | |
54 _started = false; | |
55 } | |
56 | |
57 Future<InternetAddress> lookup( | |
58 String hostname, {Duration timeout: const Duration(seconds: 5)}) { | |
59 if (!_started) { | |
60 throw new StateError('mDNS client is not started'); | |
61 } | |
62 | |
63 // Add the pending request before sending the query. | |
64 var future = _resolver.addPendingRequest(hostname, timeout); | |
65 | |
66 // Send the request. | |
67 _service.send([_incoming.sendPort, | |
68 RequestType.lookupRequest.index, | |
69 hostname]); | |
70 | |
71 return future; | |
72 } | |
73 | |
74 // Process incoming responses. | |
75 _handleIncoming(response) { | |
76 // Right not the only response we can get is the response to a | |
77 // lookupRequest where the response looks like this: | |
78 // | |
79 // response[0]: hostname (String) | |
80 // response[1]: IPv4 address (Uint8List) | |
81 if (response is List && response.length == 2) { | |
82 if (response[0] is String && | |
83 response[1] is List && response[1].length == 4) { | |
84 response = new DecodeResult(response[0], | |
85 new InternetAddress(response[1].join('.'))); | |
86 _resolver.handleResponse([response]); | |
87 } else { | |
88 // TODO(sgjesse): Improve the error handling. | |
89 print('mDNS Response not understood'); | |
90 } | |
91 } | |
92 } | |
93 } | |
94 | |
95 Future nativeExtensionEchoTest(dynamic message) async { | |
96 SendPort service = servicePort(); | |
97 ReceivePort port = new ReceivePort(); | |
98 try { | |
99 service.send([port.sendPort, RequestType.echoRequest.index, message]); | |
100 return await port.first; | |
101 } finally { | |
102 port.close(); | |
103 } | |
104 } | |
105 | |
106 SendPort servicePort() native 'MDnsExtension_ServicePort'; | |
OLD | NEW |