UNPKG

nativescript-dna-netservices

Version:

NativeScript plugin for Bonjour/ZeroConf and network monitoring. RxJS based APIs for Android and iOS.

136 lines 5.6 kB
import { Observable, throwError } from "rxjs"; import { android as androidApplication } from "@nativescript/core/application"; import { mapError } from "./zeroconf-service.common"; import { ZeroConf, zeroConfStatus, zeroConfError, addressType } from "./netservice.common"; import { startWith } from "rxjs/operators"; export class ZeroConfService { constructor() { this._rxdnssd = new com.github.druk.rx2dnssd.Rx2DnssdBindable(androidApplication.context); } publish(o) { if (o.port === 0) { const port = ZeroConfService.availablePort(); if (port < 0) throwError(zeroConfError.failedToFindAvailablePort); else o.port = port; } const observable = new Observable((observer) => { const bs = new com.github.druk.rx2dnssd.BonjourService.Builder(0, 0, o.name, o.type, o.domain) .port(o.port) .build(); const onNext = new io.reactivex.functions.Consumer({ accept: bonjourService => { const status = zeroConfStatus.success; observer.next(ZeroConfService.getZeroConf(status, bonjourService)); } }); const onError = new io.reactivex.functions.Consumer({ accept: ec => { const zc = new ZeroConf({ status: zeroConfStatus.failed, domain: o.domain, type: o.type, name: o.name, port: o.port }); observer.error({ errorCode: mapError(ec), zeroConf: zc }); } }); const disposable = this._rxdnssd .register(bs) .subscribeOn(io.reactivex.schedulers.Schedulers.io()) .observeOn(io.reactivex.android.schedulers.AndroidSchedulers.mainThread()) .subscribe(onNext, onError); return () => disposable.dispose(); }); return observable.pipe(startWith(new ZeroConf({ status: zeroConfStatus.serviceBegins, domain: o.domain, type: o.type, name: o.name, port: o.port }))); } resolve(o) { const observable = new Observable((observer) => { const isMatchingName = new io.reactivex.functions.Predicate({ test: bonjourService => bonjourService.getServiceName() === o.name }); const onNext = new io.reactivex.functions.Consumer({ accept: bonjourService => { let addrs = []; if (bonjourService.getInet4Address()) { const address = bonjourService.getInet4Address().getHostAddress(); if (address) addrs.push({ address: address, type: addressType.IPv4 }); } if (bonjourService.getInet6Address()) { const address = bonjourService.getInet6Address().getHostAddress(); if (address) addrs.push({ address: address, type: addressType.IPv6 }); } const status = zeroConfStatus.success; observer.next(ZeroConfService.getZeroConf(status, bonjourService, addrs)); } }); const onError = new io.reactivex.functions.Consumer({ accept: ec => { const zc = new ZeroConf({ status: zeroConfStatus.failed, domain: o.domain, type: o.type, name: o.name }); observer.error({ errorCode: mapError(ec), zeroConf: zc }); } }); const disposable = this._rxdnssd .browse(o.type, o.domain) .filter(isMatchingName) .compose(this._rxdnssd.resolve()) .compose(this._rxdnssd.queryIPRecords()) .subscribeOn(io.reactivex.schedulers.Schedulers.io()) .observeOn(io.reactivex.android.schedulers.AndroidSchedulers.mainThread()) .take(1) .subscribe(onNext, onError); return () => disposable.dispose(); }); return observable.pipe(startWith(new ZeroConf({ status: zeroConfStatus.serviceBegins, domain: o.domain, type: o.type, name: o.name }))); } stop() { console.assert(false, "On Android stop api is not implemented."); } static getZeroConf(status, bonjourService, addrs) { return new ZeroConf({ status: status, domain: bonjourService.getDomain(), type: bonjourService.getRegType(), hostName: bonjourService.getHostname(), name: bonjourService.getServiceName(), port: bonjourService.getPort(), addresses: addrs }); } static availablePort() { let socket = null; try { socket = new java.net.ServerSocket(0); socket.setReuseAddress(true); const port = socket.getLocalPort(); try { socket.close(); } catch (exception) { } return port; } catch (ex) { } return -1; } } //# sourceMappingURL=zeroconf-service.android.js.map