# ReactiveNetwork **Repository Path**: HarmonyOS-tpc/ReactiveNetwork ## Basic Information - **Project Name**: ReactiveNetwork - **Description**: ReactiveNetwork is an OHOS library listening network connection state and internet connectivity with RxJava Observables. - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: RxJava1.x - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 0 - **Created**: 2021-04-15 - **Last Updated**: 2023-04-17 ## Categories & Tags **Categories**: harmonyos-network **Tags**: None ## README # ReactiveNetwork ReactiveNetwork : ReactiveNetwork is an OHOS library listening **network connection state** and **internet connectivity** with RxJava Observables. It's written with Reactive Programming approach. ReactiveNetwork includes : * Observing network connectivity. * Checking Internet Connectivity continuously and/or once. * Supporting custom host using own InternetObservingStrategy. * Supporting Chaining network and Internet connectivity streams. # Usage Instructions Sample application require following permissions: ``` ohos.permission.INTERNET ohos.permission.GET_NETWORK_INFO ``` cleartextTraffic support is disabled by default for HTTP. However, HTTPS is supported by default. To support HTTP, need to add "network" to the config.json file, and set the attribute "cleartextTraffic" to true. ``` { "deviceConfig": { "default": { "network": { "cleartextTraffic": true } } } } ``` ### Observing network connectivity We can observe `Connectivity` with `observeNetworkConnectivity(context)` method in the following way: ``` ReactiveNetwork .observeNetworkConnectivity(context) .subscribeOn(Schedulers.io()) ... // anything else what you can do with RxJava .observeOn(HarmonySchedulers.mainThread()) .subscribe(connectivity -> { // do something with connectivity // you can call connectivity.getNetworkState(); // or connectivity.getNetworkCapabilities(); } ,throwable -> { /* handle error here */} ); ``` When `Connectivity` changes, subscriber will be notified. `Connectivity` can change its state or type. **Errors** can be handled in the same manner as in all RxJava observables. For example: ``` ReactiveNetwork .observeNetworkConnectivity(context) .subscribeOn(Schedulers.io()) .observeOn(HarmonySchedulers.mainThread()) .subscribe( connectivity -> /* handle connectivity here */, throwable -> /* handle error here */ ); ``` ### Observing Internet connectivity #### Observing Internet connectivity continuously We can observe connectivity with the Internet continuously in the following way: ``` ReactiveNetwork .observeInternetConnectivity() .subscribeOn(Schedulers.io()) .observeOn(HarmonySchedulers.mainThread()) .subscribe(isConnectedToInternet -> { // do something with isConnectedToInternet value }, throwable -> { /* handle error here */} );); ``` An `Observable` will return `true` to the subscription (disposable) if device is connected to the Internet and `false` if not. Internet connectivity will be checked _as soon as possible_. **Please note**: This method is less efficient than `observeNetworkConnectivity(context)` method, because in default observing strategy, it opens socket connection with remote host every two seconds with two seconds of timeout and consumes data transfer. Use this method if you really need it. Optionally, you can dispose subscription (disposable) right after you get notification that Internet is available and do the work you want in order to decrease network calls. Methods in this section should be used if they are really needed due to specific use cases. If you want to customize observing of the Internet connectivity, you can use `InternetObservingSettings` class and its builder. They allow to customize monitoring interval in milliseconds, host, port, timeout, initial monitoring interval, timeout, expected HTTP response code, error handler or whole observing strategy. ``` InternetObservingSettings settings = InternetObservingSettings.builder() .initialInterval(initialInterval) .interval(interval) .host(host) .port(port) .timeout(timeout) .httpResponse(httpResponse) .errorHandler(testErrorHandler) .strategy(strategy) .build(); ReactiveNetwork .observeInternetConnectivity(settings) .subscribeOn(Schedulers.io()) .observeOn(HarmonySchedulers.mainThread()) .subscribe(isConnectedToInternet -> { // do something with isConnectedToInternet value }, throwable -> { /* handle error here */} );); ``` These methods are created to allow the users to fully customize the library and give them more control. Please note, not all parameters are relevant for all strategies. #### Checking Internet Connectivity once If we don't want to observe Internet connectivity in the interval with `Observable observeInternetConnectivity(...)` method, we can use `Single checkInternetConnectivity()`, which does the same thing, but **only once**. It may be helpful in the specific use cases. ``` Single single = ReactiveNetwork.checkInternetConnectivity(); single .subscribeOn(Schedulers.io()) .observeOn(HarmonySchedulers.mainThread()) .subscribe(isConnectedToInternet -> { // do something with isConnectedToTheInternet }, throwable -> { /* handle error here */} );); ``` As in the previous case, you can customize this feature with the `InternetObservingSettings` class and its builder. ``` InternetObservingSettings settings = InternetObservingSettings.builder() .initialInterval(initialInterval) .interval(interval) .host(host) .port(port) .timeout(timeout) .httpResponse(httpResponse) .errorHandler(testErrorHandler) .strategy(strategy) .build(); Single single = ReactiveNetwork.checkInternetConnectivity(settings); single .subscribeOn(Schedulers.io()) .observeOn(HarmonySchedulers.mainThread()) .subscribe(isConnectedToInternet -> { // do something with isConnectedToTheInternet }, throwable -> { /* handle error here */} );); ``` Basic idea is the same. With just have `Single` return type instead of `Observable` and we don't have `int initialIntervalInMs` and `int intervalInMs` parameters. As previously, these methods are created to allow the users to fully customize the library and give them more control. #### Internet Observing Strategies Right now, we have the following strategies for observing Internet connectivity: - `SocketInternetObservingStrategy` - monitors Internet connectivity via opening socket connection with the remote host - `WalledGardenInternetObservingStrategy` - opens connection with a remote host and respects countries in the Walled Garden (e.g. China) All of these strategies implements `NetworkObservingStrategy` interface. Default strategy used right now is `WalledGardenInternetObservingStrategy`, but with `checkInternetConnectivity(strategy)` and `observeInternetConnectivity(strategy)` method we can use one of these strategies explicitly. #### Custom host If you want to ping custom host during checking Internet connectivity, it's recommended to use `SocketInternetObservingStrategy`. You can do it as follows: ``` InternetObservingSettings settings = InternetObservingSettings.builder() .host("www.yourhost.com") .port(port) .strategy(new SocketInternetObservingStrategy()) .build(); ReactiveNetwork .observeInternetConnectivity(settings) .subscribeOn(Schedulers.io()) .observeOn(HarmonySchedulers.mainThread()) .subscribe(isConnectedToHost -> { // do something with isConnectedToHost }, throwable -> { /* handle error here */} );); ``` If you want to use `WalledGardenInternetObservingStrategy`, please update HTTP response code via `InternetObservingSettings`. E.g set it to `200` because default is `204`. The same operation can be done with `checkInternetConnectivity(strategy, host)` method, which returns `Single` instead of `Observable`. ### Chaining network and Internet connectivity streams Let's say we want to react on each network connectivity change and if we get connected to the network, then we want to check if that network is connected to the Internet. We can do it in the following way: ``` ReactiveNetwork .observeNetworkConnectivity(getApplicationContext()) .flatMapSingle(connectivity -> ReactiveNetwork.checkInternetConnectivity()) .subscribeOn(Schedulers.io()) .observeOn(HarmonySchedulers.mainThread()) .subscribe(isConnected -> { // isConnected can be true or false }, throwable -> { /* handle error here */} );); ``` In case we're getting too many events related to the network changes or we want to discard previous observables (there's only one in the code snippet above) after subscribing them, we can use `switchMapSingle` operator instead of `flatMapSingle` in order to get the updates from the latest observable only. In this case, it will be observable created by `checkInternetConnectivity` method. # Installation Instructions Library Dependencies ReactiveNetwork is dependent on rxohos.har,rxjava3 and gson. 1. For using ReactiveNetwork module in your sample application, include the below library dependency to generate hap/library.har. Modify entry build.gradle as below : ``` dependencies { implementation 'io.openharmony.tpc.thirdlib:Rxohos:1.0.0' implementation 'io.reactivex.rxjava3:rxjava:3.0.4' implementation 'com.google.code.gson:gson:2.8.6' implementation project(path: ':library') } ``` 2. For using ReactiveNetwork in separate application, add the below dependencies and "library.har" in libs folder of "entry" module. Modify entry build.gradle as below : ``` dependencies { implementation fileTree(dir: 'libs', include: ['*.har']) implementation 'io.openharmony.tpc.thirdlib:Rxohos:1.0.0' implementation 'io.reactivex.rxjava3:rxjava:3.0.4' implementation 'com.google.code.gson:gson:2.8.6' } ``` 3. For using ReactiveNetwork from a remote repository in separate application, add the below dependencies in "entry" build.gradle. Modify entry build.gradle as below : ``` dependencies { implementation 'io.openharmony.tpc.thirdlib:Rxohos:1.0.0' implementation 'io.openharmony.tpc.thirdlib:ReactiveNetwork:1.0.2' implementation 'io.reactivex.rxjava3:rxjava:3.0.4' implementation 'com.google.code.gson:gson:2.8.6' } ``` # License ``` Copyright 2016 Piotr Wittchen Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ```