Azure IoT Hub messages late/delay/drop - node.js

Azure IoT Hub on server side and Azure IoT Client SDK on Device side, we are found 60-65 seconds delay and
drop between device sent a status message over MQTT and message was received by IoT Hub.
In some cases, we are seeing 1-2 minutes delay when IoT Hub enqueued the message.
Below is the code for communication with device to device
//'use strict';
//DeviceToCloudMessages libraries
var EventHubClient = require('azure-event-hubs').Client;
//var base64 = require('base-64');
//*NK+1 19-02-18 CloudToDeviceMessage Libraries
var Registry = require('azure-iothub').Registry;
//CloudToDeviceMessage libraries
var Client = require('azure-iothub').Client;
var Message = require('azure-iot-common').Message;
//*NK+1 13-03-18 Get constant values stored in GlobalConstants js
var constant = require('./GlobalConstants');
var connectionString = constant.connectionString;
var serviceClient = Client.fromConnectionString(connectionString);
//*NK+ 16-03-18 Open service cline
serviceClient.open(function (err) {
if (err) {
console.error('Could not connect: ' + err.message);
} else {
console.log('Open connection: ');
}
});
//*NK+1 19-02-18 Create registry for connection string
var registry = Registry.fromConnectionString(connectionString);
//To prevent memory leak
require('events').EventEmitter.defaultMaxListeners = Infinity;
//To check device connection state
var request = require('request');
auth = constant.authorization;
//Datetime library
date = require('date-and-time');
var moment = require("moment");
//For log
const fs = require('fs');
var datetime = require('node-datetime');
//For database connection
var sql = require('mssql');
var config =
{
user: constant.sUsername, // update me
password: constant.sPassword, // update me
server: constant.sServer, // update me
database: constant.sDatabase,
options: {
encrypt: true
},
//*start 30-01-18 set resource request timeout
connectionTimeout: 0,
requestTimeout: 0,
pool: {
max: 100,
min: 1,
idleTimeoutMillis: 30000
}
//*end 30-01-18 set resource request timeout
}
//*NK+1 23-03-18 declare flag false
//var isLog = false;
// sql.close();
//SQL starts
sql.connect(config).then(function (err) {
if (err) {
//console.log('sql CONNECTION ERROR');
console.log(err);
}
console.log('Opening connection');
var printError = function (err) {
logmsg(err.message);
logmsg('Error from event hub:', err.message);
startReceiver();
};
function logmsg(msg)
{
//if(isLog){
try {
//console.log(msg);
var dt = datetime.create();
var formatted = dt.format('Y-m-d H:M:S');
var date = dt.format('Y-m-d');
var checkhr = dt.format('H');
var filepath = 'D:/home/site/wwwroot/WebJobLogs/SendD2DMsgLog_' +date +'_' +checkhr + '-00-00' +'.txt';
fs.appendFile(filepath, formatted + " " + msg + "\n");
} catch(error) {
//console.log(error);
}
//}
}
function printResultFor(op) {
try {
return function printResult(err, res) {
if (err)
{
logmsg(op + ' error: ' + err.toString());
}
if (res)
{
logmsg(op + ' status: ' + res.constructor.name);
}
};
} catch (exception) {
logmsg("Print result function " + exception)
}
}
function receiveFeedback(err, receiver) {
receiver.on('message', function (msg) {
logmsg('IOT Feedback message:')
logmsg(msg.getData().toString('utf-8'));
});
}
//*NK+start 19-02-18 for firmware update
function queryTwinFWUpdateReported(deviceToUpdate) {
logmsg('deviceToUpdate : ' + deviceToUpdate);
logmsg('deviceToUpdate : ' + deviceToUpdate);
registry.getTwin(deviceToUpdate, function(err, twin){
if (err) {
//console.error('Could not query twins: ' + err.constructor.name + ': ' + err.message);
logmsg('Could not query twins: ' + err.constructor.name + ': ' + err.message);
} else {
//console.log('queryTwinFWUpdateReported: ' + (JSON.stringify(twin.properties.reported.iothubDM.firmwareUpdate)) + "\n");
//logmsg((JSON.stringify(twin.properties.reported.iothubDM.firmwareUpdate)) + "\n");
}
});
}
function startFirmwareUpdateDevice (linkString, deviceToUpdate) {
//console.log('linkString: ' + linkString);
var params = {
FwPackageUri: linkString
};
var methodName1 = "FirmwareUpdate";
var payloadData = JSON.stringify(params);
var payloadData1 = JSON.parse(payloadData);
logmsg('payloadData : ' + payloadData1);
var methodParams = {
methodName: methodName1,
payload: payloadData1,
timeoutInSeconds: 3600//,
//responseTimeoutInSeconds: 3600
};
//var methodParamsTest = JSON.stringify(methodParams);
//var objmethodParams = JSON.parse(methodParamsTest);
logmsg('methodParams : ' + JSON.stringify(methodParams));
//console.log('methodParams : ' + JSON.stringify(methodParams));
serviceClient.invokeDeviceMethod(deviceToUpdate, methodParams, function(err, result) {
if (err) {
//console.log('Could not start the firmware update on the device: ' + err.message);
//console.log('Device: ' + err.stack);
logmsg('Could not start the firmware update on the device: ' + err.message);
}else{
logmsg('success result : ' + JSON.stringify(result));
//console.log('success result : ' + JSON.stringify(result));
}
});
}
//*NK+end 19-02-18 for firmware update
var printMessage = function (message) {
logmsg('Message received: ');
try {
var chunk_msg = JSON.stringify(message.body);
logmsg(chunk_msg);
var obj = JSON.parse(chunk_msg);
//*NK+start 19-02-18 firmware update code
if(obj.hasOwnProperty('firmwareUpdate')){
var firmwaretype= obj.controllerName;
var firmwaremodel= obj.modelNumber;
var firmwareDeviceId = obj.firmwareUpdate;
var appDeviceId = obj.appDeviceId;
new sql.Request()
.query("SELECT f.fw_version, f.[loc] FROM <<table>> f WHERE f.[Type] = '" + firmwaretype + "' ").then(function (recordset) {
var statusLocation = JSON.stringify(recordset);
var obj = JSON.parse(statusLocation);
var result = obj.recordset;
logmsg('result: ' + result);
console.log('result: ' + result);
if(result.length > 0){
console.log('fw_version: ' + result[0].fw_version);
console.log('loc: ' + result[0].loc);
console.log('obj.firmwareUpdate : ' + firmwareDeviceId);
console.log('obj.appDeviceId : ' + appDeviceId);
new sql.Request()
.query("select TOP 1 * from <<table>> where Id = '" + firmwareDeviceId + "' order by id desc ").then(function (recordset) {
var status = JSON.stringify(recordset);
var objstatus = JSON.parse(status);
var resultstatus = objstatus.recordset;
var datastatus = resultstatus[0];
var chunkstatus = JSON.stringify(datastatus);
var objnewstatus = JSON.parse(chunkstatus);
var endDate = objnewstatus.last_update;
logmsg('controller last status date ' + endDate);
console.log('controller last status date ' + endDate);
now = new Date();
var currentDate = date.format(now, 'YYYY-MM-DD HH:mm:ss');
logmsg('server current date ' + currentDate);
console.log('server current date ' + currentDate);
var start_date = moment(currentDate, 'YYYY-MM-DD HH:mm:ss');
var end_date = moment(endDate, 'YYYY-MM-DD HH:mm:ss');
var duration = moment.duration(start_date.diff(end_date));
var hours = duration.asHours();
//var seconds = Math.abs(hours * 3600);
var seconds = Math.abs(hours * 3600);
logmsg('difference in seconds ' + seconds);
console.log('difference in seconds ' + seconds);
if (seconds < 40)
{
logmsg('fw_version: ' + result[0].fw_version);
logmsg('loc: ' + result[0].loc);
console.log('fw_version: ' + result[0].fw_version);
console.log('loc: ' + result[0].loc);
startFirmwareUpdateDevice(result[0].loc, firmwareDeviceId);
setInterval(function() {queryTwinFWUpdateReported(firmwareDeviceId);}, 1000);
}
else{
//format failure msg to send to app
var result = '{"response_status":"true","device_id":"' + firmwareDeviceId + '"}';
logmsg('Sending message to app:' + result);
console.log('Sending message to app:' + result);
var message = new Message(result);
serviceClient.send(appDeviceId, message, printResultFor('send'));
logmsg('Feedback Message for firmware upgrade failure sent to app ' + appDeviceId);
console.log('Feedback Message for firmware upgrade failure sent to app ' + appDeviceId);
}
}).catch(function (err) {
logmsg('firmware upgrade: ' + err);
});
}
}).catch(function (err) {
logmsg(err);
});
}
//*NK+end 19-02-18
if (obj.hasOwnProperty('command'))
{
logmsg('command exist');
console.log('command exist');
//Send Msg to device
//serviceClient.open(function (err) {
//if (err) {
// console.error('Could not connect: ' + err.message);
//} else {
// logmsg('Service client connected');
//*NK+1 23-03-18 Commented feedback receiver
//serviceClient.getFeedbackReceiver(receiveFeedback);
message.ack = 'full';
//message.messageId = "My Message ID";
//*NK+1 20-02-18 Update messageId
console.log('obj.messageId : ' + obj.messageId);
message.messageId = obj.messageId;
//Check the status of controller before sending message and return message to user in case of failure
var targetDevice = obj.deviceId;
new sql.Request()
.query("select TOP 1 * from <<table>> where Id = '" + targetDevice + "' order by id desc ").then(function (recordset) {
var status = JSON.stringify(recordset);
var objstatus = JSON.parse(status);
var resultstatus = objstatus.recordset;
var datastatus = resultstatus[0];
var chunkstatus = JSON.stringify(datastatus);
var objnewstatus = JSON.parse(chunkstatus);
var endDate = objnewstatus.last_update;
logmsg('controller last status date ' + endDate);
console.log('controller last status date ' + endDate);
now = new Date();
var currentDate = date.format(now, 'YYYY-MM-DD HH:mm:ss');
logmsg('server current date ' + currentDate);
console.log('server current date ' + currentDate);
var start_date = moment(currentDate, 'YYYY-MM-DD HH:mm:ss');
var end_date = moment(endDate, 'YYYY-MM-DD HH:mm:ss');
var duration = moment.duration(start_date.diff(end_date));
var hours = duration.asHours();
//var seconds = Math.abs(hours * 3600);
var seconds = Math.abs(hours * 3600);
logmsg('difference in seconds ' + seconds);
console.log('difference in seconds ' + seconds);
if (seconds <= 65)
{
var data = obj.command;
//format msg to send to controller
var str1 = '{"Name":"Play","Parameters":{"Data":"';
var res = str1.concat(data);
var str2 = '"}}';
var result = res.concat(str2);
var message = new Message(result);
logmsg('Sending message to controller: ' + message.getData());
console.log('Sending message to controller: ' + message.getData());
serviceClient.send(targetDevice, message, printResultFor('send'));
logmsg('Message sent to controller ' + targetDevice);
console.log('Message sent to controller ' + targetDevice);
}
else
{
//*NK+start 29-03-18 Check reset command and send to the server
var data_command = obj.command;
if(data_command == "<<RESETDEVICECOMMAD>>"){
//format msg to send to controller
var str1 = '{"Name":"Play","Parameters":{"Data":"';
var res = str1.concat(data_command);
var str2 = '"}}';
var result = res.concat(str2);
var message = new Message(result);
logmsg('Reset message is: ' + message.getData());
console.log('Reset message is: ' + message.getData());
serviceClient.send(targetDevice, message, printResultFor('send'));
logmsg('Reset message sent to controller ' + targetDevice);
console.log('Reset message sent to controller ' + targetDevice);
}
//*NK+start 29-03-18 Check reset command and send to the server
if (obj.hasOwnProperty('appDeviceId'))
{
//Get app device id
var AppDeviceId = obj.appDeviceId;
//format failure msg to send to app
var result = '{"response_status":"false","device_id":"' + targetDevice + '"}';
logmsg('Sending message to app:' + result);
console.log('Sending message to app:' + result);
var message = new Message(result);
serviceClient.send(AppDeviceId, message, printResultFor('send'));
logmsg('Feedback Message for command failure sent to app ' + AppDeviceId);
console.log('Feedback Message for command failure sent to app ' + AppDeviceId);
}
}
}).catch(function (err) {
logmsg(err);
});
// }
//});
}
else if (obj.hasOwnProperty('u32SH'))
{
// console.log('json exist');
var deviceId = obj.deviceId;
var data = chunk_msg;
var datetime = new Date();
//SQL to get list of device ids
new sql.Request()
.query("select * from <<table>> where id in (select id from <<table>> where id in (select id from <<table>> where Id = '" + deviceId + "')) and connectionState = 'Connected' ").then(function (recordset) {
var chunk = JSON.stringify(recordset);
var obj = JSON.parse(chunk);
var result = obj.recordset;
var message = new Message(chunk_msg);
message.ack = 'full';
message.messageId = "My Message ID";
logmsg('Sending message: ' + message.getData());
for (var i = 0, len = result.length; i < len; i++)
{
var data = result[i];
var chunk1 = JSON.stringify(data);
var obj1 = JSON.parse(chunk1);
//Get device id of user
var targetDevice = obj1.device_id;
serviceClient.send(targetDevice, message, printResultFor('send'));
logmsg('Message sent to user ' + targetDevice);
} //for loop ends
}).catch(function (err) {
logmsg(err);
}); //1st sql ends
} //else if for json object check ends
//*NK++ 06-03-18 update controller table
var macId = obj.deviceId;
updateControllerFirmwareVersion(macId);
} catch (exception) {
logmsg("Handling exception....");
logmsg(exception);
}
}; //printMessage function ends
//*NK+start 05-03-18 update controller firmware version
function updateControllerFirmwareVersion(deviceId){
registry.getTwin(deviceId, function(err, twin){
if (err) {
//console.log('Could not query twins: ' + err.constructor.name + ': ' + err.message);
console.error('Could not query twins: ' + err.constructor.name + ': ' + err.message);
} else {
logmsg((JSON.stringify(twin.properties.reported.AzureFwVersion)) + "\n");
//console.log((JSON.stringify(twin.properties.reported.AzureFwVersion)) + "\n");
//var azureFwVersion = twin.properties.reported.AzureFwVersion.replace('Azure_Sns_DM V','');
var azureFwVersion = twin.properties.reported.AzureFwVersion;
var s = azureFwVersion.lastIndexOf(".");
var res = azureFwVersion.substring(s+1, azureFwVersion.length);
//console.log('azureFwVersion: ' + res);
var firmwareV = Number(res).toString(16).toUpperCase() + '00';
//console.log('hex : ' + firmwareV);
logmsg('hex : ' + firmwareV);
new sql.Request()
.query("select fw_version from <<table>> where Id = '" + deviceId + "'").then(function (recordset) {
logmsg('Get current controller table firmware version');
var currentData = JSON.stringify(recordset);
var obj = JSON.parse(currentData);
var resultstatus = obj.recordset;
var datastatus = resultstatus[0];
var chunkstatus = JSON.stringify(datastatus);
var objnewstatus = JSON.parse(chunkstatus);
if(objnewstatus.fw_version != firmwareV){
console.log('Available firmware is ' + firmwareV);
logmsg('Available firmware is ' + firmwareV);
new sql.Request()
.query("UPDATE <<table>> SET fw_version = '" + firmwareV + "' where Id = '" + deviceId + "'").then(function (recordset) {
logmsg('Updated Controller table for firmware');
//console.log('Updated Controller table for firmware');
}).catch(function (err) {
logmsg('Qry to update Controller table for firmware' + err);
//console.log('Qry to update Controller table for firmware' + err);
});
}
}).catch(function (err) {
logmsg('Qry to update Controller table for firmware' + err);
//console.log('Qry to update Controller table for firmware' + err);
});
}
});
}
//*NK+end 05-03-18 update controller firmware version
var startReceiver = function () {
try {
logmsg('Receiver on');
var client = EventHubClient.fromConnectionString(connectionString);
client.open()
.then(client.getPartitionIds.bind(client))
.then(function (partitionIds) {
return partitionIds.map(function (partitionId) {
return client.createReceiver('$Default', partitionId, {'startAfterTime': Date.now()}).then(function (receiver) {
logmsg('Created partition receiver: ' + partitionId)
// receiver.on('errorReceived', printError);
// receiver.on('message', printMessage);
receiver.on('errorReceived', function callback() {
// console.log('Error Received in receiver');
client.close()
startReceiver()
});
receiver.on('message', printMessage);
});
})
})
// .catch(printError);
.catch(function callback() {
logmsg('Error Received in catch');
client.close()
startReceiver()
});
} catch (exception) {
logmsg("startReceiver function " + exception)
}
};
startReceiver();
}); //sql connection ends
Question:
1. What is the reason for this late/delay/drop in message reaching to IoT Hub?
2. Is there any issue on node js code?
I am using following node js packages :
{
"name": "Haven",
"version": "1.0.0",
"description": "",
"main": "AppToServerToDevice.js",
"dependencies": {
"azure-event-hubs": "0.0.8",
"azure-iot-device": "^1.2.1",
"azure-iot-device-mqtt": "^1.2.2",
"azure-iothub": "^1.2.3",
"base-64": "^0.1.0",
"date-and-time": "^0.6.2",
"heapdump": "^0.3.9",
"moment": "^2.20.1",
"mssql": "^4.1.0",
"tedious": "^2.1.1"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
IOT Hub details :
IoT Hub details:
Pricing tier: S2 standard
IoT Hub units: 1
SQL database Pricing tier is Standard: S3
Please suggest.
Please see below sample log.
2018-04-02 14:00:18 Message received:
2018-04-02 14:00:23 send status: MessageEnqueued
2018-04-02 14:00:23 send status: MessageEnqueued
2018-04-02 14:00:23 send status: MessageEnqueued
2018-04-02 14:00:23 send status: MessageEnqueued
2018-04-02 14:00:25 {"deviceId":"<<FAKE_ID>>","messageId":54,"u32SH":1094861843,"u32SVN":1215,"u32CVN":645,"u32SRS":2,"u32EVT_ID":9,"u8RSSI":94,"u8C1TID":0,"u8C1ETID":1,"u8C1STId":0,"u8C1ATId":1,"u8C1Rt":3,"u8C1B":36,"u8C1WL":0,"u8C1WB":36,"u8C1SB":68,"u8C1PB":0,"u8C2TID":0,"u8C2ETID":1,"u8C2STId":0,"u8C2ATId":2,"u8C2Rt":11,"u8C2B":99,"u8C2WL":11,"u8C2WB":99,"u8C2SB":99,"u8C2PB":99,"ts":"2018-04-02T14:00:23Z"}
2018-04-02 14:00:25 Message sent to user <<FAKE_ID>>
2018-04-02 14:00:25 Message sent to user <<FAKE_ID>>
2018-04-02 14:00:26 IOT Feedback message:
2018-04-02 14:00:26 [{"originalMessageId":"My Message ID","description":"Success","deviceGenerationId":"636573862820707504","deviceId":"34cebb0dd9eab292","enqueuedTimeUtc":"2018-04-02T14:00:18.6513817Z","statusCode":"Success"},{"originalMessageId":"My Message ID","description":"Success","deviceGenerationId":"636573862820707504","deviceId":"34cebb0dd9eab292","enqueuedTimeUtc":"2018-04-02T14:00:22.9953077Z","statusCode":"Success"}]

Related

Firebase cloud function sending multiple notification on instanceId

Thats my code where i first get the laterrides. It checks that the any ride is schedule and if any ride is scheduled then it goes inside and get the list of drivers and sends them notification. But the issue is it send notification repeatedly again and again.Kindly help.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.testing = functions.https.onRequest((req, res) => {
console.log("start");
var newArray = [];
let date = new Date();
var hours = date.getHours() + 5;
var minute = date.getMinutes() ;
var year = date.getFullYear() ;
var month = date.getUTCMonth() + 1 ;
var day = date.getDate() ;
var total_date = day + "/" + month + "/" + year;
var total_time = hours + ":" + minute;
var ridelater = admin.database().ref("ridelater");
ridelater.orderByValue().on("value", function(snapshot) {
snapshot.forEach(function(data) {
var str = data.val().time;
const senderUid = data.val().client_key;
if(data.val().date == total_date){
var arr = str.split(":");
var start_minute = arr[0] * 60;
var val = parseInt(arr[1], 10);
var timing = val - 30;
var start = start_minute + timing ;
var end_minute = hours *60;
var end = end_minute + minute;
var diff = end - start;
if (diff <= 30){
var driver = admin.database().ref("user/driver");
driver.orderByValue().on("value", function(snapshot) {
snapshot.forEach(function(instnaceIds) {
//if(instnaceIds.val().status == "free"){
const promises = [];
const receiverUid = instnaceIds.key;
const getInstanceIdPromise =
admin.database().ref(`/user/driver/${receiverUid}/instanceId`)
.once('value');
const getSenderUidPromise = admin.auth().getUser(senderUid);
Promise.all([getInstanceIdPromise, getSenderUidPromise]).then(results =>
{
const instanceId = results[0].val();
//const sender = results[1];
console.log('notifying ' + receiverUid +' from ' + senderUid);
var data1={
'users_key': senderUid,
'org_address' : data.val().org_address,
'dest_address' : data.val().dest_address,
'status' : "request",
'Nodekey' : data.key,
'user_name' : data.val().user_name,
'org_lat' : data.val().org_lat,
'org_long' : data.val().org_long,
'dest_lat' : data.val().dest_lat,
'dest_long' : data.val().dest_long,
'payment' : data.val().payment_method,
'category' : data.val().category,
'Nodekey' : data.val().node_key,
};
var data2 = JSON.stringify(data1);
console.log(JSON.stringify(data1));
const payload = {
notification: {
title: "Qandeel Haider",
body: data2
}
};
console.log(payload);
return admin.messaging().sendToDevice(instanceId, payload)
.then(function (response) {
console.log("Successfully sent message:" + instanceId);
})
.catch(function (error) {
console.log("Error sending message:", error);
});
});
//}
});
});
}
else{
console.log("Not found" + data.val().time);
}
}
else{
console.log("Not found" + data.val().date);
}
console.log("IN");
});
});
console.log("end");
res.status(200).end();
});

Node reply to tweet does not actually reply

I'm using the Twit Node library to reply to tweets in a stream and while it's working perfectly the tweeted reply does not show up as a reply on the timeline, instead, it appears as a standalone tweet, not linked to a prior conversation.
Here's my code:
function tweetEvent(eventMsg) {
var replyto = eventMsg.in_reply_to_screen_name;
var text = eventMsg.text;
var from = eventMsg.user.screen_name;
console.log(replyto + ' ' + from);
if( (text.indexOf('myhandle') >= 0) || (from != 'myhandle')) {
var reply = replies[Math.floor(Math.random() * replies.length)];
var newtweet = '#' + from + ' ' + reply;
tweetIt(newtweet);
}
}
function tweetIt(txt) {
var tweet = {
status: txt
}
T.post('statuses/update', tweet, tweeted);
function tweeted(err, data, response) {
if (err) {
console.log("Something went wrong!");
} else {
console.log("It worked!");
}
}
}
In order for the reply to show up in the timeline using the Twitter API, you need the following:
// the status update or tweet ID in which we will reply
var nameID = eventMsg.id_str;
Also needed is the parameter in_reply_to_status_id in your tweet status. See the updates to your code below and it should now preserve the conversation:
function tweetEvent(eventMsg) {
var replyto = eventMsg.in_reply_to_screen_name;
var text = eventMsg.text;
var from = eventMsg.user.screen_name;
// the status update or tweet ID in which we will reply
var nameID = eventMsg.id_str;
console.log(replyto + ' ' + from);
if( (text.indexOf('myhandle') >= 0) || (from != 'myhandle')) {
var reply = replies[Math.floor(Math.random() * replies.length)];
var newtweet = '#' + from + ' ' + reply;
tweetIt(newtweet);
}
function tweetIt(txt) {
var tweet = {
status: txt,
in_reply_to_status_id: nameID
}
}
T.post('statuses/update', tweet, tweeted);
function tweeted(err, data, response) {
if (err) {
console.log("Something went wrong!");
} else {
console.log("It worked!");
}
}
}

TypeError: Cannot read property 'emails' of null

Here is line 54, where I am getting the error:
if (docr.emails) {
And here is the rest of my original code:
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
var ObjectId = require('mongodb').ObjectID;
var config = require('./config'),
xlsx = require('./xlsx'),
utils = require('./utils'),
_ = require('lodash'),
url = config.DB_URL;
var meetings = [];
function findNumberOfNotesByMeeting(db, meeting, callback) {
var meetingId = meeting._id.toString(),
meetingName = meeting.name.displayValue,
attendees = meeting.attendees;
host = meeting.host;
var count = 1, pending = 0, accepted = 0;
console.log("==== Meeting: " + meetingName + '====');
_.each(attendees, function(item) {
console.log(count++ + ': ' + item.email + ' (' + item.invitationStatus + ')');
if (item.invitationStatus == 'pending') { pending++; }
else if (item.invitationStatus == 'accepted') { accepted++; }
});
console.log("*** " + attendees.length + ", " + pending + "," + accepted);
db.collection('users').findOne({'_id': new ObjectId(host)}, function(err, doc) {
var emails = [];
if (doc.emails) {
doc.emails.forEach(function(e) {
emails.push(e.email + (e.primary ? '(P)' : ''));
});
}
var email = emails.join(', ');
if (utils.toSkipEmail(email)) {
callback();
} else {
db.collection('notes').find({ 'meetingId': meetingId }).count(function(err, count) {
if (count != 0) {
console.log(meetingName + ': ' + count + ',' + attendees.length + ' (' + email + ')');
meetings.push([ meetingName, count, email, attendees.length, pending, accepted ]);
}
callback();
});
}
});
}
function findMeetings(db, meeting, callback) {
var host = meeting.host;
db.collection('users').findOne({'_id': new ObjectId(host)}, function(err, docr) {
var emails = [];
if (docr.emails) {
docr.emails.forEach(function(e) {
emails.push(e.email + (e.primary ? '(P)' : ''));
});
}
var email = emails.join(', ');
if (utils.toSkipEmail(email)) {
callback();
} else {
var cursor = db.collection('meetings').find({
'email': {'$regex': 'abc', '$options': 'i' }
});
}
cursor.count(function(err, count) {
console.log('count: ' + count);
var cnt = 0;
cursor.each(function(err, doc) {
assert.equal(err, null);
if (doc != null) {
findNumberOfNotesByMeeting(db, doc, function() {
cnt++;
if (cnt >= count) { callback(); }
});
}
});
});
});
};
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
findMeetings(db, function() {
var newMeetings = meetings.sort(function(m1, m2) { return m2[1] - m1[1]; });
newMeetings.splice(0, 0, [ 'Meeting Name', 'Number of Notes', 'Emails' ]);
xlsx.writeXLSX(newMeetings, config.xlsxFileNameMeetings);
db.close();
});
});
Try the following:
function findMeetings(db, meeting, callback) {
var host = meeting.host;
db.collection('users').findOne({'_id': new ObjectId(host)}, function(err, docr) {
var emails = [];
if (!err && docr && docr.emails) {
docr.emails.forEach(function(e) {
emails.push(e.email + (e.primary ? '(P)' : ''));
});
}
...

node js gettting error of activity timeout or database connection lost

I am using node js script to sync data(for multiple users) from GeoTab server APIs to my local db and using below code
var syncUsers = function () {
for (var i = 0; i < geotabUsers.length; i++) {
if (apiInstanse[geotabUsers[i].userId] == undefined)
{
apiInstanse[geotabUsers[i].userId] = new API(geotabUsers[i].apiUsername, geotabUsers[i].apiPassword, geotabUsers[i].apiDatabase, js_lang.GEOTAB_SERVER);
}
syncStatusData(apiInstanse[geotabUsers[i].userId], i, userInfo[geotabUsers[i].userId].statusDataFromVersion, geotabUsers[i].userId, userInfo[geotabUsers[i].userId].currentCompany, geotabUsers[i].apiUsername, geotabUsers[i].apiPassword, geotabUsers[i].apiDatabase);
}
var syncStatusData = function (api, i, fromVersion, userId, currentCompany, apiUsername, apiPassword, apiDatabase){
try {
api.call(js_lang.GEOTAB_GETFEED_METHOD, {
typeName: js_lang.GEOTAB_STATUS_DATA,
resultsLimit: js_lang.GEOTAB_API_LIMIT,
fromVersion: fromVersion
}, function (err, data) {
if (err) {
console.log('api Call Error:', userId);
console.log('apiUsername:', apiUsername);
console.log('apiPassword:', apiPassword);
console.log('apiDatabase:', apiDatabase);
console.log('Error', err);
apiInstanse[userId] = new API(apiUsername, apiPassword, apiDatabase, js_lang.GEOTAB_SERVER);
return;
}
var insertStatus = [];
var sql = "INSERT INTO " + js_lang.TABLE_STATUS_DATA + " (companyId,dateTime,deviceId ,diagnosticId,value,version,uniqueId,userId,unitOfMeasure ) VALUES ?";
//iterate data
if (data.data != undefined)
{
for (var key in data.data) {
if (diagnosticList[data.data[key].diagnostic.id] == undefined)
{
continue;
}
var thisDate = moment(new Date(data.data[key].dateTime));
var thisDayDate = thisDate.format("YYYY-MM-DD");
//prepare data to insert
var insertRow = [
currentCompany,
thisDate.format("YYYY-MM-DD HH:MM:ss"),
data.data[key].device.id,
data.data[key].diagnostic.id,
data.data[key].data,
data.data[key].version,
data.data[key].id,
userId,
diagnosticList[data.data[key].diagnostic.id].unitOfMeasure
];
insertStatus.push(insertRow);
var todayDate = moment(new Date());
var todayDayDate = todayDate.format("YYYY-MM-DD");
//send alert in case of current day data
if (todayDayDate == thisDayDate)
{
//send mails in case of high pressure
if (diagnosticList[data.data[key].diagnostic.id].unitOfMeasure == js_lang.GEOTAB_PRESSURE_UNIT_STR &&
data.data[key].data > js_lang.MAX_PRESSURE &&
alertTemplates[userId] != undefined)
{
console.log('alert time');
if (alertTemplates[userId] != undefined)
{
for (var templateIndex = 0; templateIndex < alertTemplates[userId].length; templateIndex++) {
var template = alertTemplates[userId][templateIndex];
var res = template.devices.split(",");
var index = FUNCTION_CLASS.contains.call(res, data.data[key].device.id)
if (index)
{
var emailSubject = 'High Pressure Alert';
if (userDevices[userId][data.data[key].device.id].name != undefined)
{
var emailText = 'Vehicle:' + userDevices[userId][data.data[key].device.id].name;
}
else
{
var emailText = '';
}
var toEmails = template.emails;
var emailHtml = 'Vehicle:' + userDevices[userId][data.data[key].device.id].name + '<br>' + diagnosticList[data.data[key].diagnostic.id].name + ' <br> value:' + data.data[key].data + ' ' + js_lang.GEOTAB_PRESSURE_UNIT_PA + '<br>\
' + js_lang.DATE_TIME + ':' + thisDate.format("YYYY-MM-DD HH:MM:ss");
//call mail function
sendEmail(toEmails, emailSubject, emailText, emailHtml);
}
}
}
}
}
}
}
if (insertStatus.length > 0)
{
connection.query(sql, [insertStatus], function (err) {
if (err)
throw err;
connection.query('UPDATE ' + js_lang.TABLE_USER + ' SET statusDataFromVersion = ? WHERE id = ?',
[data.toVersion, userId]);
});
}
else {
console.log('update user:', userId);
connection.query('UPDATE ' + js_lang.TABLE_USER + ' SET statusDataFromVersion = ? WHERE id = ?',
[data.toVersion, userId]);
}
if ((geotabUsers.length - 1) == i)
{
console.log('loop ended');
continueSync();
}
});
}
catch (e) {
continueSync();
}
}
var continueSync = function () {
setTimeout(function () {
connection.end();
geotabUsers = [];
userDevices = [];
diagnosticList = [];
userInfo = [];
alertTemplates = {};
eventEmitter.emit('getUsers');
}, 60000);
}
Its work fine for few iteration but getting random errors like
events.js:85
throw er; // Unhandled 'error' event
^
Error: Quit inactivity timeout
Or
events.js:85
throw er; // Unhandled 'error' event
^
Error: Connection lost: The server closed the connection.
I was getting this error while executing app on local, To remove problem I have used pm2 node module for process management.Now its working fine.

Node.js how to handle packet fragmentation with net.Server

When a net.Server receives data that exceeds 1500 bytes (default mtu), the 'on data' event is executed with each fragment of the packet. Is there a way to receive the whole packet in a single 'on data' call?
Thanks.
Try this
var sys = require('sys');
var net = require('net');;
var socktimeout = 600000;
var svrport = your_port;
var svr = net.createServer(function(sock) {
var mdata = new Buffer(0);
//sys.puts('Connected: ' + sock.remoteAddress + ':' + sock.remotePort);
sock.setTimeout(socktimeout,function(){
sock.end("timeout");
sock.destroy();
});
sock.on('data', function(data) {
if(mdata.length != 0)
{
var tempBuf = Buffer.concat([mdata, data]);
mdata = tempBuf;
}
else
{
mdata = data;
}
var len=got_your_Packget_length(mdata);
if(mdata.length == len)
{
do_your_job(mdata)
mdata = new Buffer(0);
}
});
sock.on('error', function(err) { // Handle the connection error.
sys.puts('error: ' + err +'\n');
});
});
svr.listen(svrport);

Resources