how to check internet connectivity in node.js, electron - javascript

I'm trying to detect internet connectivity in node.js and electron.
my code notifies internet connectivity every 1 second.
but what I want is showing connectivity when it's connected, disconnected
(only when connection is switched ) not every 1 second.
can I do that in node.js and electron?
main.js
const dns = require('dns');
function liveCheck() {
dns.resolve('www.google.com', function(err, addr){
if (err) {
notifier.notify(
{
appName: "com.myapp.id",
title: "network error",
message: "disconnected",
icon:"./facebook.png"
}
);
}
else{
console.log("connected");
}
});
}
setInterval(function() {
liveCheck()
},1000);

navigator.onLine is not reliable method. So i found npm util to handle this situation
Install it npm i check-internet-connected
And use it
const checkInternetConnected = require('check-internet-connected');
const config = {
timeout: 5000, //timeout connecting to each try (default 5000)
retries: 3,//number of retries to do before failing (default 5)
domain: 'apple.com'//the domain to check DNS record of
}
checkInternetConnected(config)
.then(() => {
console.log("Connection available");
}).catch((err) => {
console.log("No connection", err);
});

This works for me in the latest Electron version 4.0.8 on macOS, from a renderer process, using only Web API:
function notifyUser (event)
{
let myNotification = new Notification
(
"com.myapp.id",
{ body: (event.type === 'online') ? "Internet available" : "No internet" }
);
}
window.addEventListener ('online', notifyUser, false);
window.addEventListener ('offline', notifyUser, false);
References:
navigator.onLine
Online and offline events
Notification

If you were to keep the same logic, you need to add a flag to see if you switched from no connection to connected. I did that with the isConnected
flag:
const dns = require("dns");
let isConnected = false;
function liveCheck() {
dns.resolve("www.google.com", function(err, addr) {
if (err) {
if (isConnected) {
notifier.notify({
appName: "com.myapp.id",
title: "network error",
message: "disconnected",
icon: "./facebook.png",
});
}
isConnected = false;
} else {
if (isConnected) {
//connection is still up and running, do nothing
} else {
notifier.notify({
appName: "com.myapp.id",
title: "connection gained",
message: "connected",
icon: "./facebook.png",
});
}
isConnected = true;
}
});
}
setInterval(function() {
liveCheck();
}, 1000);

First, install internet-available package
npm install internet-available
And then,
var internetAvailable = require("internet-available");
// Set a timeout and a limit of attempts to check for connection
internetAvailable({
timeout: 4000,
retries: 10,
}).then(function(){
console.log("Internet available");
}).catch(function(){
console.log("No internet");
});

Related

PAHO js more then one connection not possible?

I connect with PAHO Javascript to my mosquitto broker. If i connect with a second client, the first one will be disconnected. With the timeout of 2 Seconds the conetions wil be ping back and force, but can this be the reight solution?
var client = new Paho.MQTT.Client("192.168.5.100", 9880, "/", "mybro");
var reconnectTimeout = 2500;
function connectMqtt(){
console.log("connecting to mqtt ...");
try {
client.connect({
timeout: 3,
onSuccess: onConnect,
useSSL: false,
userName: "user",
password: "password",
keepAliveInterval: 30,
reconnect : false
});
} catch (error) {
console.log(error);
}
client.onConnectionLost = onConnectionLost;
client.onMessageArrived = onMessageArrived;
}
function onConnect() {
try {
client.subscribe("shellies/#");
client.subscribe("openWB/#");
console.log("Connected!");
} catch (error) {
console.log(error);
}
}
function onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0) {
console.log("onConnectionLost:"+responseObject.errorMessage);
setTimeout(connectMqtt, reconnectTimeout);
}
}
function onMessageArrived(message) {
setDataToGui(message.destinationName, message.payloadString);
}
What did I try? Everything, what i have found in internet. There should be a problem in my code.
I need to connect with more then one Webbrowser (clients).
var client = new Paho.MQTT.Client("192.168.5.100", 9880, "/", "mybro");
The problem is the last entry in this function. It is the client ID that must be unique to EVERY client connecting to the broker.
You will need to generate the value most likely as a random number or a very high precision timestamp to limit the chances of 2 clients generating the sme value.

PeerJS error when trying to call another peer: Failed to execute 'addStream' on 'RTCPeerConnection': parameter 1 is not of type 'MediaStream'

I am successfully establishing a connection between two peers using PeerJS but whenever I try passing a MediaStream object to the .call function I get this error:
Failed to execute 'addStream' on 'RTCPeerConnection': parameter 1 is
not of type 'MediaStream'
Everything else works great, connection is indeed established, both peers receive messages from each other via the 'open' event. The only thing that doesn't work is the peer.call() function. The microphone is properly captured after requesting the permission to do so.
Am I making some kind of a mistake here? I'd appreciate any help. Thank you.
Here is my code:
var media;
jQuery(document).ready(function() {
var peer = new Peer({
key: 'xxxxxxxxxxxxx'
});
media = navigator.mediaDevices.getUserMedia({
audio: true,
video: false
});
peer.on('open', function(id) {
console.log('My peer ID is: ' + id);
});
var conn = peer.connect(callID);
conn.on('open', function() {
// Receive messages
conn.on('data', function(data) {
console.log('Received', data);
});
// Send messages
conn.send('Hello!');
});
console.log(typeof(media));
var call = peer.call(callID, media);
peer.on('error', function(err) {
console.log(err);
});
});
I'd be interested to see the output of console.log(typeof(media));.
According to the MDN website, it seems that the following line will return a Promise instead of a MediaStream:
media = navigator.mediaDevices.getUserMedia({audio: true, video: false});
The following should work:
var media;
jQuery(document).ready(function() {
var peer = new Peer({
key: 'xxxxxxxxxxxxx'
});
navigator.mediaDevices.getUserMedia({
audio: true,
video: false
})
.then(function(mediaStream) {
peer.on('open', function(id) {
console.log('My peer ID is: ' + id);
});
var conn = peer.connect(callID);
conn.on('open', function() {
// Receive messages
conn.on('data', function(data) {
console.log('Received', data);
});
// Send messages
conn.send('Hello!');
});
console.log(typeof(media));
var call = peer.call(callID, mediaStream);
peer.on('error', function(err) {
console.log(err);
});
});
});

Cannot insert to collection from NPM using Meteor 1.3

I am using the imap-simple NPM package to check emails, and I am having trouble getting the insert to work properly.
I have already read through this page: https://guide.meteor.com/using-npm-packages.html#async-callbacks - and I have tried the suggestions but none of them are working!
I've also simplified the code a bit just to try to get it working, but still have no luck.
The problem should be very easy to reproduce - meteor npm install imap-simple, throw the above code on the server, add some email credentials, and call the method.
Here is my code:
var imaps = require('imap-simple');
var config = {
imap: {
user: '<removed>',
password: '<removed>',
host: 'imap.gmail.com',
port: 993,
tls: true,
authTimeout: 3000
}
};
Meteor.methods({
api_connectEmail: function () {
console.log('Received call to connect email');
imaps.connect(config).then(function (connection) {
return connection.openBox('INBOX').then(function () {
var searchCriteria = [
'UNSEEN'
];
var fetchOptions = {
bodies: ['HEADER', 'TEXT'],
markSeen: true
};
return connection.search(searchCriteria, fetchOptions).then(function (results) {
results.map(function (res) {
var subject = res.parts.filter(function (part) {return part.which === 'HEADER';})[0].body.subject[0];
console.log("Subject: " + subject);
// insert
var attributes = {
subject: subject
};
console.log("Attempting to insert to collection...");
var newData = TempEmailCollection.insert(attributes);
console.log("New Database Entry ID: " + newData);
});
});
});
})
}
});
The console.log with the subject is working. The insert is not working. No error, no console.log post insert, nothing.
I've tried both strategies recommended in the guide, neither work.
The problem is that you are calling a Meteor function inside asynchronously called Promise handlers.
However, all Meteor functions that are called on the server have to run in a fiber.
Meteor actually throws an error in this case but you are ignoring it because you haven't specified catch functions for the Promises.
Consider the following simplified example (it just connects to the server and tries to insert a new document):
import { Meteor } from 'meteor/meteor';
import imaps from 'imap-simple';
const Storage = new Mongo.Collection('storage');
const config = {
imap: {
…
}
};
Meteor.methods({
connect() {
console.log('Method called');
imaps.connect(config).then(function(connection) {
console.log('Connected');
Storage.insert({
value: 'success'
});
console.log('Document inserted');
})
.catch(function(err) {
console.error(err);
});
}
});
The following message will arrive in the catch function:
[Error: Meteor code must always run within a Fiber. Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment.]
You could do something like this to wrap the insert call:
Meteor.methods({
connect() {
console.log('Method called');
const insert = Meteor.bindEnvironment(function() {
Storage.insert({
value: 'success'
});
});
imaps.connect(config).then(function(connection) {
console.log('Connected');
insert();
console.log('Document inserted');
})
.catch(function(err) {
console.error(err);
});
}
});
Then the document will be inserted as expected.

Wait for ServiceWorker to complete registering before subscribing

I am using a ServiceWorker to implement user notifications. When the user first visits the site and approves the notification, the ServiceWorker is registered and subscribed to:
if ('serviceWorker' in navigator) {
console.log('Service Worker is supported');
navigator.serviceWorker.register('/js/sw.js').then(function(reg) {
if(/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())){
reg.pushManager.subscribe({
userVisibleOnly: true
}).then(function(sub) {
console.log('endpoint:', sub.endpoint);
endpoint = sub.endpoint;
fetch(MY_API+encodeURIComponent(endpoint), {
credentials: 'include'
})
});
}
}).catch(function(err) {
console.log(':^(', err);
});
}
On the very first visit, this failes with:
Uncaught (in promise) DOMException: Subscription failed - no active Service Worker
From the second visit on, everything is OK because the ServiceWorker is already active at that time. Looks like this is a timing issue. How can I be sure the ServiceWorker has been registered successfully and is active before I try to subscribe to it?
I tried using navigator.serviceWorker.ready as suggested below:
if ('serviceWorker' in navigator) {
console.log('Service Worker is supported');
navigator.serviceWorker.register('/js/sw.js').then(function(sreg) {
console.log(':^)', sreg);
navigator.serviceWorker.ready.then(function(reg) {
if(/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())){
reg.pushManager.subscribe({
userVisibleOnly: true
}).then(function(sub) {
console.log('endpoint:', sub.endpoint);
endpoint = sub.endpoint;
fetch("https://www.wettfreun.de/?page=fetch&s=1&endpoint="+encodeURIComponent(endpoint), {credentials: 'include'})
});
}
});
}).catch(function(err) {
console.log(':^(', err);
});
}
Now the part inside navigator.serviceWorker.ready.then() is never called.
You can use ServiceWorkerContainer.ready.
Example from MDN:
function subscribe() {
var subscribeButton = document.querySelector('.js-subscribe-button');
subscribeButton.disabled = false;
navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
serviceWorkerRegistration.pushManager.subscribe()
.then(function(subscription) {
// The subscription was successful
subscribeButton.disabled = true;
return sendSubscriptionToServer(subscription);
})
.catch(function(error) {
if (Notification.permission === 'denied') {
console.log('Permission for Notifications was denied');
subscribeButton.disabled = true;
} else {
console.log('Unable to subscribe to push.', error);
subscribeButton.disabled = false;
}
});
});
}

Using chrome push notifications mainfest.json in meteor project

I am following a guide on how to implement the chrome push notification and I am trying to implement it in a Meteor app as a package.
Because I am unable to include the manifest.json I am getting "Registration failed - no sender id provided" or "Registration failed - permission denied". So how can I include this file in my project?
The manifest.json looks like this:
{
"permissions": [ "gcm" ],
"name": "push",
"short_name": "push notification",
"display": "standalone",
"gcm_sender_id": "0000000000000"
}
I have tried including it with the package.js like:
api.addAssets('manifest.json', 'client');
And also put the required variables (gcm_sender_id) in settings.json and starting meteor with meteor --settings settings.json but nothing works.
My service worker registration starts with calling Cpn.serviceWorkerRegistration:
Cpn = {};
Cpn.serviceWorkerRegistration = function () {
console.log("serviceWorkerRegistration called");
subscribe();
console.log(navigator);
// Check that service workers are supported, if so, progressively
// enhance and add push messaging support, otherwise continue without it.
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js')
.then(initialiseState);
} else {
console.warn('Service workers aren\'t supported in this browser.');
}
}
// Once the service worker is registered set the initial state
initialiseState = function () {
console.log("initialiseState");
// Are Notifications supported in the service worker?
if (!('showNotification' in ServiceWorkerRegistration.prototype)) {
console.warn('Notifications aren\'t supported.');
return;
}
// Check the current Notification permission.
// If its denied, it's a permanent block until the
// user changes the permission
if (Notification.permission === 'denied') {
console.warn('The user has blocked notifications.');
return;
}
// Check if push messaging is supported
if (!('PushManager' in window)) {
console.warn('Push messaging isn\'t supported.');
return;
}
// We need the service worker registration to check for a subscription
navigator.serviceWorker.ready.then(function (serviceWorkerRegistration) {
// Do we already have a push message subscription?
serviceWorkerRegistration.pushManager.getSubscription()
.then(function (subscription) {
if (!subscription) {
return;
}
// Keep your server in sync with the latest subscriptionId
sendSubscriptionToServer(subscription);
})
.catch(function (err) {
console.warn('Error during getSubscription()', err);
});
});
}
function subscribe() {
navigator.serviceWorker.ready.then(function (serviceWorkerRegistration) {
serviceWorkerRegistration.pushManager.subscribe()
.then(function (subscription) {
// The subscription was successful
// TODO: Send the subscription.endpoint to your server
// and save it to send a push message at a later date
return sendSubscriptionToServer(subscription);
})
.catch(function (e) {
if (Notification.permission === 'denied') {
// The user denied the notification permission which
// means we failed to subscribe and the user will need
// to manually change the notification permission to
// subscribe to push messages
console.warn('Permission for Notifications was denied');
} else {
// A problem occurred with the subscription; common reasons
// include network errors, and lacking gcm_sender_id and/or
// gcm_user_visible_only in the manifest.
console.error('Unable to subscribe to push.', e);
}
});
});
}
And the service worker looks like this:
self.addEventListener('push', showNotification)
self.addEventListener('notificationclick', closeNotificationAndOpenWindow)
function showNotification(event) {
console.log('Received a push message', event)
var title = 'Yay a message.'
var body = 'We have received a push message.'
var icon = '/images/icon-192x192.png'
var tag = 'simple-push-demo-notification-tag'
event.waitUntil(
self.registration.showNotification(title, {
body: body,
icon: icon,
tag: tag
})
)
}
function closeNotificationAndOpenWindow(event) {
console.log('On notification click: ', event.notification.tag)
// Android doesn’t close the notification when you click on it
// See: http://crbug.com/463146
event.notification.close()
// This looks to see if the current is already open and
// focuses if it is
event.waitUntil(clients.matchAll({
type: "window"
}).then(function (clientList) {
for (var i = 0; i < clientList.length; i++) {
var client = clientList[i]
if (client.url == '/' && 'focus' in client)
return client.focus()
}
if (clients.openWindow)
return clients.openWindow('/')
}))
}

Categories

Resources