nativescript-dna-netservices
by Deepak Arora | v2.0.1
NativeScript plugin for Bonjour/ZeroConf and network monitoring. RxJS based APIs for Android and iOS.
npm i --save nativescript-dna-netservices

NativeScript DNA NetServices

nativescript-dna-netservices

NativeScript 8.0 based plugin for Bonjour/ZeroConf and network monitoring. RxJS based APIs for service discovery, browsing and publication, and networking monitoring.

The plugin offers cross-platform utility APIs to retrieve or query Bonjour/ZeroConf related information. The APIs are available for iOS and Android platforms.

Kindly visit typescript demo repository for practical implementation guidance and hints. The demo is tested with iOS and Android devices.

The Changelogs selection is located towards the end of the document.

I welcome an appreciation email with suggestions and feedback. It will encourage me to provide new APIs and support. My email-id is Deepak Arora. Enjoy and I will be looking forward to your valuable feedback.

Features

  • Cross-platform APIs for Android and iOS
  • Service Discovery, Resolution, Browse, and Publication
  • Monitor network availability
  • WiFi and Cellular IP address retrieval

More about Bonjour/ZerConf can be found at: Apple’s Bonjour implementation and Android mDNSResponder

Installation

From the command prompt go to your app's root folder and execute:

tns plugin add nativescript-dna-netservices

This command automatically installs the necessary files, as well as stores nativescript-dna-netservices as a dependency in your project's package.json file.

  • Notes for iOS users:

    Please refer to NSBonjourServices for necessary changes to your Info.plist file.

    Example of Info.plist:

    <dict>
    <!--Describe the permissions, features or other configurations required by your plugin for iOS.-->
    <key>NSLocalNetworkUsageDescription</key>
    <string>Privacy - Local Network Usage Description</string>

    <key>NSBonjourServices</key>
    <array>
    <string>_http._tcp</string>
    <string>_ipp._tcp</string>
    <string>_yourservice._tcp</string>
    </array>
    </dict>

API

NativeScript DNA NetServices APIs are classified into the following services:

  • NetworkMonitorService: Provides API for monitoring network availability and accessing device IP address
  • ZeroConfService: Deals with service resolution and publication part of Bonjour/ZeroConf
  • ZeroConfServiceBrowser: Involves with service browsing part of Bonjour/ZeroConf

Each of these services with their APIs is covered below.

- NetworkMonitorService

Depending on the type of framework, NetworkMonitorService can be imported using one of the following ways:

TypeScript:

import { NetworkMonitorService } from "nativescript-dna-netservices";

JavaScript:

const nativescript_dna_netservices = require("nativescript-dna-netservices");
const NetworkMonitorService = nativescript_dna_netservices.NetworkMonitorService;

Below are the APIs available in NetworkMonitorService:

getWiFiIpAddress: Retrieves IPv4 address of a device assigned for communication in a WiFi network.

NetworkMonitorService.getWiFiIpAddress().subscribe(
ipAddr => console.info(ipAddr),
err => console.error(err),
() => console.log("completed")
);

getCellularIpAddress: Gets IPv4 address of a device used for communication in a mobile/cellular network. It's not a public IP address.

NetworkMonitorService.getCellularIpAddress().subscribe(
ipAddr => console.info(ipAddr),
err => console.error(err),
() => console.log("completed")
);

dumpIpAddress: Gets various addresses (IPv4 and IPv6) of a device attached to interface cards. Observer's next handler receives an array of type IAddress if addresses are retrieved successfully.

NetworkMonitorService.dumpIpAddress().subscribe(
addrs => console.info(addrs),
err => console.error(err),
() => console.log("completed")
);

getNetworkStatus: Depending on a network type a device is connected to, it gets network status which includes connection type (wifi, cellular, or none) and IPv4 address. If for some reason the device is not on a network, then the status would be an empty address with the connection type none.

NetworkMonitorService.getNetworkStatus().subscribe(
networkStatus => console.info(networkStatus.connType, networkStatus.ipAddress),
err => console.error(err),
() => console.log("completed")
);

monitorNetwork: It tracks and notifies of any changes in network condition a device sees. If for some reason the device is not on a network, then the status would be an empty address with the connection type none.

const networkStatusSubscription = NetworkMonitorService.monitorNetwork()
.subscribe(ns => {
let connType = "";
switch (ns.connType) {
case networkType.wifi:
connType = "WiFi";
break;
case networkType.cellular:
connType = "Cellular";
break;
default:
connType = "Unavailable";
}
console.info(connType, ns.ipAddress);
});

- ZeroConfService

The ZeroConfService class represents a network service, either one your application publishes or is a client of. This class uses multicast DNS to convey information about network services to and from your application.

Depending on the type of framework, ZeroConfService can be imported using one of the following ways:

TypeScript:

import { ZeroConfService } from "nativescript-dna-netservices";

JavaScript:

const nativescript_dna_netservices = require("nativescript-dna-netservices");
const ZeroConfService = nativescript_dna_netservices.ZeroConfService;

Below are the APIs offered by ZeroConfService:

publish: Provides a convenient way for publishing a network service of type type at the socket location specified by domain, name, and port. In the event of success, observer's next handler receives data of type ZeroConf. Furthermore, in the event of failure, the error handler receives an error object which looks like { errorCode: zeroConfError, zeroConf: ZeroConf }. Both ZeroConf and zeroConfError can be imported using one of the above-mentioned ways from nativescript-dna-netservices.

const zeroConfService = new ZeroConfService();
const registrationSubscription = zeroConfService
.publish({
domain: "local.",
type: "_my_special_radio_service._tcp.",
name: "Radio Service",
port: 61234
})
.subscribe(data => console.info(data), error => console.error(error));
  • Note: The API will use one of the available free port in the system, if the specified port is 0.

resolve: Performs a resolve process for the service of a given type and name within a specified domain. If the service is available, observer's next handler receives ZeroConf data which contains socket information for your application to connect to the service. In the event of failure, the error handler receives an error object which looks like { errorCode: zeroConfError, zeroConf: ZeroConf }.

const zeroConfService = new ZeroConfService();
const registrationSubscription = zeroConfService
.resolve({
domain: "local.",
type: "_my_special_radio_service._tcp.",
name: "Radio Service"
})
.subscribe(data => console.info(data), error => console.error(error));

- ZeroConfServiceBrowser

The ZeroConfServiceBrowser class offers a possibility to browse services of a certain type within a given domain.

Depending on the type of framework, ZeroConfServiceBrowser can be imported using one of the following ways:

TypeScript:

import { ZeroConfServiceBrowser } from "nativescript-dna-netservices";

JavaScript:

const nativescript_dna_netservices = require("nativescript-dna-netservices");
const ZeroConfServiceBrowser = nativescript_dna_netservices.ZeroConfServiceBrowser;

Below are the APIs offered by ZeroConfServiceBrowser:

searchForServicesOfTypeInDomain: Starts a search for services of a particular type within a specific domain.

const zeroConfServiceBrowser = new ZeroConfServiceBrowser();
const subscription = zeroConfServiceBrowser
.searchForServicesOfTypeInDomain("_my_special_radio_service._tcp", "local.")
.subscribe(data => console.info(data), error => console.error(error));

If the services are available, observer's next handler will be invoked multiple times with ZeroConf data which your application can use to resolve to socket info to make network connection. And, if there is an error, the error handler receives a zeroConfError error code.

Combining ZeroConfService & ZeroConfServiceBrowser

Sometimes functionalities from these services can be combined together to create new purposes. One of the use cases is to have socket information for every browsed service. To accomplish this, RxJS pipeable operators come in handy. Below is the sample snippet illustrating the same.

const patternToSearch = /^radio_channel/i;
const serviceFinderTimeout = timer(3000);
const serviceFinder = zeroConfServiceBrowser
.searchForServicesOfTypeInDomain("_my_special_radio_service._tcp", "local.")
.pipe(
filter(service => service.name && service.name.match(patternToSearch).length > 0),
distinct(),
concatMap(service =>
zeroConfService.resolve(service).pipe(
filter(service => service.status === zeroConfStatus.success),
take(1),
observeOn(asyncScheduler)
)
),
takeUntil(serviceFinderTimeout)
);

serviceFinder.subscribe(
service => console.info(service),
error => console.error(error),
() => console.info("Completed Here...")
);

Changelogs:

  • 2.0.1: Updated documention.
  • 2.0.0: Upgraded to NativeScript 8.0 version. Bumped up the vesion of various packages. Test on Android and iOS devices.
  • 1.1.0: Updated documention.
  • 1.0.0: First release.

License

MIT license (see LICENSE file)