| // Copyright 2015 The Vanadium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| import 'dart:async'; |
| |
| import 'package:discovery/discovery.dart' as discovery; |
| import 'package:flutter/services.dart' show embedder; |
| |
| class ProxyHandlePair<T> { |
| final T proxy; |
| int handle; |
| |
| ProxyHandlePair(this.proxy, this.handle); |
| } |
| |
| /// Make this into the Dart Discovery client |
| /// https://github.com/vanadium/issues/issues/835 |
| class DiscoveryClient { |
| final Map<String, ProxyHandlePair<discovery.AdvertiserProxy>> advertisers = |
| new Map<String, ProxyHandlePair<discovery.AdvertiserProxy>>(); |
| final Map<String, ProxyHandlePair<discovery.ScannerProxy>> scanners = |
| new Map<String, ProxyHandlePair<discovery.ScannerProxy>>(); |
| |
| static final String discoveryUrl = 'https://mojo2.v.io/discovery.mojo'; |
| |
| DiscoveryClient() {} |
| |
| static discovery.Service serviceMaker( |
| {List<int> instanceUuid, |
| String instanceName, |
| String interfaceName, |
| Map<String, String> attrs, |
| List<String> addrs}) { |
| // None of these are nullable, so it's nice to have a helper to create them. |
| return new discovery.Service() |
| ..instanceUuid = instanceUuid ?? new List<int>() |
| ..instanceName = instanceName ?? '' |
| ..interfaceName = interfaceName ?? '' |
| ..attrs = attrs ?? new Map<String, String>() |
| ..addrs = addrs ?? new List<String>(); |
| } |
| |
| // Scans for this query and handles found/lost objects with the handler. |
| // Keeps track of this scanner via the key. |
| Future scan(String key, String query, discovery.ScanHandler handler) async { |
| // Cancel the scan if one is already going for this key. |
| if (scanners.containsKey(key)) { |
| stopScan(key); |
| } |
| |
| discovery.ScannerProxy s = new discovery.ScannerProxy.unbound(); |
| |
| print('Starting up discovery scanner ${key}. Looking for ${query}'); |
| |
| embedder.connectToService(discoveryUrl, s); |
| |
| // Use a ScanHandlerStub (Mojo-encodable interface) to wrap the scan handler. |
| discovery.ScanHandlerStub shs = new discovery.ScanHandlerStub.unbound(); |
| shs.impl = handler; |
| |
| print('Scanning begins!'); |
| return s.ptr |
| .scan(query, shs) |
| .then((discovery.ScannerScanResponseParams response) { |
| print( |
| "${key} scanning started. The cancel handle is ${response.handle}."); |
| scanners[key] = |
| new ProxyHandlePair<discovery.ScannerProxy>(s, response.handle); |
| }); |
| } |
| |
| // This sends a stop signal to the scanner. Since it is non-blocking, the |
| // scan handle may not stop instantaneously. |
| void stopScan(String key) { |
| print("Stopping scan for ${key}."); |
| scanners[key].proxy.ptr.stop(scanners[key].handle); |
| scanners[key].proxy.close(); // don't wait for this future. |
| scanners.remove(key); |
| } |
| |
| // Advertises the given service information. Keeps track of the advertiser |
| // handle via the key. |
| Future advertise(String key, discovery.Service serviceInfo, |
| {List<String> visibility}) async { |
| // Cancel the advertisement if one is already going for this key. |
| if (advertisers.containsKey(key)) { |
| stopAdvertise(key); |
| } |
| |
| discovery.AdvertiserProxy a = new discovery.AdvertiserProxy.unbound(); |
| |
| print( |
| 'Starting up discovery advertiser ${key}. Broadcasting for ${serviceInfo.instanceName}'); |
| |
| embedder.connectToService(discoveryUrl, a); |
| |
| return a.ptr |
| .advertise(serviceInfo, visibility ?? <String>[]) |
| .then((discovery.AdvertiserAdvertiseResponseParams response) { |
| print( |
| "${key} advertising started. The cancel handle is ${response.handle}."); |
| advertisers[key] = |
| new ProxyHandlePair<discovery.AdvertiserProxy>(a, response.handle); |
| }); |
| } |
| |
| // This sends a stop signal to the advertiser. Since it is non-blocking, the |
| // advertise handle may not stop instantaneously. |
| void stopAdvertise(String key) { |
| print("Stopping advertise for ${key}."); |
| advertisers[key].proxy.ptr.stop(advertisers[key].handle); |
| advertisers[key].proxy.close(); // don't wait for this future. |
| advertisers.remove(key); |
| } |
| } |