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/native_extension_api.dart' |
| 14 deferred as native_extension_api; |
| 15 import 'package:mdns/src/packet.dart'; |
| 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 await native_extension_api.loadLibrary(); |
| 39 _service = native_extension_api.servicePort(); |
| 40 _incoming = new ReceivePort(); |
| 41 _incoming.listen(_handleIncoming); |
| 42 |
| 43 _starting = false; |
| 44 _started = true; |
| 45 } |
| 46 |
| 47 void stop() { |
| 48 if (!_started) return; |
| 49 if (_starting) { |
| 50 throw new StateError('Cannot stop mDNS client wile it is starting'); |
| 51 } |
| 52 |
| 53 _incoming.close(); |
| 54 |
| 55 _started = false; |
| 56 } |
| 57 |
| 58 Future<InternetAddress> lookup( |
| 59 String hostname, {Duration timeout: const Duration(seconds: 5)}) { |
| 60 if (!_started) { |
| 61 throw new StateError('mDNS client is not started'); |
| 62 } |
| 63 |
| 64 // Add the pending request before sending the query. |
| 65 var future = _resolver.addPendingRequest(hostname, timeout); |
| 66 |
| 67 // Send the request. |
| 68 _service.send([_incoming.sendPort, |
| 69 RequestType.lookupRequest.index, |
| 70 hostname]); |
| 71 |
| 72 return future; |
| 73 } |
| 74 |
| 75 // Process incoming responses. |
| 76 _handleIncoming(response) { |
| 77 // Right not the only response we can get is the response to a |
| 78 // lookupRequest where the response looks like this: |
| 79 // |
| 80 // response[0]: hostname (String) |
| 81 // response[1]: IPv4 address (Uint8List) |
| 82 if (response is List && response.length == 2) { |
| 83 if (response[0] is String && |
| 84 response[1] is List && response[1].length == 4) { |
| 85 response = new DecodeResult(response[0], |
| 86 new InternetAddress(response[1].join('.'))); |
| 87 _resolver.handleResponse([response]); |
| 88 } else { |
| 89 // TODO(sgjesse): Improve the error handling. |
| 90 print('mDNS Response not understood'); |
| 91 } |
| 92 } |
| 93 } |
| 94 } |
| 95 |
| 96 Future nativeExtensionEchoTest(dynamic message) async { |
| 97 await native_extension_api.loadLibrary(); |
| 98 SendPort service = native_extension_api.servicePort(); |
| 99 ReceivePort port = new ReceivePort(); |
| 100 try { |
| 101 service.send([port.sendPort, RequestType.echoRequest.index, message]); |
| 102 return await port.first; |
| 103 } finally { |
| 104 port.close(); |
| 105 } |
| 106 } |
OLD | NEW |