how to receive 10 digit number those press by user in phone. i am using "ari-client" Modula of nodejs
client.on( 'StasisStart', function (event, channel) {
channel.answer(
function (err) {
if (err) {
logger.error(err);
}
channel.play({media: 'sound:priv-callee-options'}, playback, function (err, playback) {
if(err){
return logger.error(err);
}
});
channel.on('ChannelDtmfReceived', function (event, channel) {
var digitPressed = event.digit;
if(digitPressed==1234567890){
client.channels.hold(
{channelId: channel.id},
function (err) {
console.log("Phone On Hold..");
}
);
}
});
});
});
Use application Read
pro-sip*CLI> core show application Read
-= Info about application 'Read' =-
[Synopsis]
Read a variable.
[Description]
Reads a #-terminated string of digits a certain number of times from the user
in to the given <variable>.
This application sets the following channel variable upon completion:
${READSTATUS}: This is the status of the read operation.
OK
ERROR
HANGUP
INTERRUPTED
SKIPPED
TIMEOUT
[Syntax]
Read(variable[,filename[&filename2[&...]][,maxdigits[,options[,attempts[,timeout]]]]])
[Arguments]
variable
The input digits will be stored in the given <variable> name.
filename
file(s) to play before reading digits or tone with option i
maxdigits
Maximum acceptable number of digits. Stops reading after <maxdigits>
have been entered (without requiring the user to press the '#' key).
Defaults to '0' - no limit - wait for the user press the '#' key.
Any value below '0' means the same. Max accepted value is '255'.
options
s: to return immediately if the line is not up.
i: to play filename as an indication tone from your "indication
s.conf".
n: to read digits even if the line is not up.
attempts
If greater than '1', that many <attempts> will be made in the event
no data is entered.
timeout
The number of seconds to wait for a digit response. If greater than
'0', that value will override the default timeout. Can be floating
point.
[See Also]
SendDTMF()
pro-sip*CLI>
Related
I am using web3js to subscribe to logs, I listening to swap events, the problem is that the .on(data) is so fast in giving data JavaScript can not keep up. lets say I add a variable let count = 0; each time I get a new log I increase the number ++count, sometimes the logs come so fast I get a double number.
The real problem is I need it to be in the exact order as it is coming in, that's why I give the number to each log, but that does not work.
How would I make sure that each data item I get from the log events that they are in order?
I tried to create a promise sequence
let sequence = Promise.resolve();
let count = 0;
web3.eth.subscribe('logs', {
fromBlock: block,
topics: [
[swapEvent]
]
}).on('data', (logData)=>{
sequence = sequence.then(()=>{
++count
processData(logData)
})
});
function processData(){
return new Promise(resolve=>{
// do some stuff
resolve();
})
};
In a simple test with a loop and random time to resolve this works fine, but in the actual code with socket it does not keep the order.
Anyone has some idea how I can make the socket data keep in order and process one by one?
Not sure why but my problem got solved with this.
sequence = sequence.then(()=>processData(logData))
before it was
sequence = sequence.then(()=>{
processData(logData)
})
Now its doing all in sequence.
I have a conversion that is started using a service of start conversion.
In mongo I have a field that monitors the conversion status: ready, runningA, runningB, DONE.
How can be created a step definition that wait until the status value of the field from mongo is DONE.?
If the file to be converted is large, then the conversion will take some minutes(1min ~ 30min).
I don't want to set a fix timer.
The feature is somthing like that:
Given user context
When the user starts the conversion (call the service that starts conversion)
Then the status of the conversion must be done (here I want to wait until the status is done)
You should design your features to reflect your user experience. Here you have a situation where a user can start an action and end up with two (or more) different experiences.
the conversion happens very quickly and the user can see that the conversion has completed
the conversion takes a long time and the user can see that the conversion is underway
So you need at least two different scenarios to deal with this. So lets start with
Scenario: Conversion completes immediately
Given ...
When I start the conversion
Then I should see the conversion is completed
Scenario: Conversion will take a long time to complete
Given ...
When I start the conversion
Then I should see the conversion is progressing
You probably want to explore things like
Scenario: Long running conversion has finally completed
So how does this answer you initial question? Well what it does is translate it into some different equivalent questions. Clearly any useful step definition cannot wait a long time for something to happen. If it does it makes your test suite unusable. So to test long running processes you have to use your Givens to put the process into a particular state that allows you to get an immediate response.
So in your case you would be writing Givens such as
Given my conversion has status runningA
Given my conversion has status runningB
...
and use those Givens in scenarios that explore the behaviour of your long running process.
From the above we can extract a 'rule of thumb' when cuking,
Never wait in a Then instead translate the waiting into the thing being done in a Given
See below my step definition, but I get the timeout
function timed out, ensure the promise resolves within 5000 milliseconds
When('the user waits until receive the status DONE',
let start = Date.now()
function getRunDetailsStaus() {
return getStatus(runDetailsId) //promise function and returns the status from mongoDB
}
function next() {
return getRunDetailsStaus().then(function (result) {
console.log("status: ", result.runStatus, Date.now() - start)
if (status == 'DONE') {
return status
}
else {
return next()
}
})
}
return next()
.then((response) => {
// process final results
})
.catch((error) => {
//process error
})
});```
We're running into a problem where we're getting multiple responses sent from our Node server to a web client which are connected by a socket server (socket.io). By listening with Docklight, I can see that we're really only getting a single response from the serial device, but for some reason the Node server is sending multiples, and they accumulate, so the first time you send a serial command (and it doesn't matter what commands) might only get a couple, next time a couple more, next time a couple more and so on. So if you run several serial commands, you'll get back lots of multiple responses.
Our environment is Windows 7 64 bit, Node V 4.5.0, serialport V 4.0.1. However, this needs to run on Windows, Mac & Linux when we're done. The dev team (me & one other guy) are both fairly new to Node, but otherwise capable developers.
I think what's happening is I'm not using the .flush() & .drain() functions properly and the serialport buffer still contains serial data. Our proprietary devices return either S>, or <Executed/> prompts when a command has completed, so I store the serial response in a buffer until I see one or the other, then process the data (in this example just providing a boolean response whether the device is responding with one or the other or not). For example, if I send a <CR><LF> to one of our devices, it should respond with S> (or <Executed/> depending).
The client calls into the server with this:
socket.on('getDeviceConnected', readDeviceResponse);
function readDeviceResponse(isDeviceResponding) {
console.log('getDeviceConnected');
console.log(isDeviceResponding);
}
function getDeviceConnected() {
console.log("Sending carriage return / line feed.");
socket.emit('getDeviceConnected', '\r\n');
}
And on the server, here's what I'm trying:
socket.on('getDeviceConnected', function (connectionData) {
//write over serial buffer before the write occurs to prevent command accumulation in the buffer.
serialBuffer = '';
sbeSerialPort.write(connectionData, function (err, results) {
//since there's no way to tell if the serial device hasn't responded, set a time out to return a false after allowing one second to elapse
setTimeout(function () {
console.log('Inside getDeviceConnected setTimeout');
console.log('Is serial device responding:', isSerialDeviceResponding);
if (!isSerialDeviceResponding) {
console.log('Serial device timed out.');
socket.emit('getDeviceConnected', false);
}
}, 1000);
if (err) {
console.log('Serial port error level:', err);
}
if (results) {
if (results === 2) {
console.log('Serial port is responding');
}
}
});
sbeSerialPort.on('data', function (serialData) {
isSerialDeviceResponding = true;
console.log('Does S> prompt exist?', serialData.lastIndexOf('S>'));
while(!serialData.lastIndexOf('S>') > -1 || !serialData.lastIndexOf('<Executed/>') > -1){
serialBuffer += serialData;
break;
}
if (isSerialDeviceResponding) {
socket.emit('getDeviceConnected', true);
isSerialDeviceResponding = true;
}
sbeSerialPort.flush(function (err, results) {
if (err) {
console.log(err);
return;
}
if(results){
console.log('Serial port flush return code:', results);
}
});
});
I'm not very sure about the .flush() implementation here, and I've omitted the .drain() part because neither of them seems to do much of anything (assuming they were correctly implemented).
How do I insure that there is no data left in the serialport buffer when the .write() command is complete? Or do you see other problems with how I'm handling the serial data?
Edit, Source code up on pastebin.com:
Server.js
Client.js
HTML
I'm writing an application using nodeJS 6.3.0 and aws DynamoDB.
the dynamodb holds statistics information that are added to dynamodb that are being called from 10 different function (10 different statistic measures). the interval is set to 10 seconds, which means that every 10 seconds, 10 calls to my function are being made to add all the relevant information.
the putItem function:
function putItem(tableName,itemData,callback) {
var params = {
TableName: tableName,
Item: itemData
};
docClient.put(params, function(err, data) {
if (err) {
logger.error(params,"putItem failed in dynamodb");
callback(err,null);
} else {
callback(null,data);
}
});
now... I created a queue.
var queue = require('./dynamoDbQueue').queue;
that implements a simple queue with fixed size that I took from http://www.bennadel.com/blog/2308-creating-a-fixed-length-queue-in-javascript-using-arrays.htm.
the idea is that if there is a network problem.. lets say for a minute. i want all the events to be pushed to the queue and when the problem is resolved to send queue information to dynamodb and to free the queue.
so I modified my original function to the following code:
function putItem(tableName,itemData,callback) {
var params = {
TableName: tableName,
Item: itemData
};
if (queue.length>0) {
queue.push(params);
callback(null,null);
} else {
docClient.put(params, function (err, data) {
if (err) {
queue.push(params);
logger.error(params, "putItem failed in dynamodb");
handleErroredQueue(); // imaginary function that i need to implement
callback(err, null);
} else {
callback(null, data);
}
});
}
}
but since I have 10 insert functions that runs at the same second, there is a chance of race conditions. which means that ...
execute1 - one function validated that the queue is empty... and is about to execute docClient.put() function.
execute2 - and at the same time another function returned from docClient.put() with an error and as a result it adds to the queue it's first row.
execute1 - by the time that the first function calling docClient.put(), the problem has been resolved and it successfully inserted data to dynamodb, which leaves the queue with previous data that will be released in the next iteration.
so for example if i inserted 4 rows with ids 1,2,3,4, the order of rows that will be inserted to dynamodb is 1,2,4,3.
is there a way to resolve that ?
thanks!
I think you are on right track, but instead of checking for an error and then adding into queue what I would suggest is to add every operation to queue first and then read the data from the queue every time.
For instance, in your case you call function 1,2,3,4 and it results in 1,2,4,3 because you are using the queue at a time off error/abrupt operation.
Step1: All your function will make an entry to a Queue -> 1,2,3,4
Step2: Read your queue and make an insert, if success remove the element
else redo the operation. This way it will insert in the desired sequence
Another advantage is that because you are using queue you don't have to keep very high throughputs for the table.
Edit:
I guess you just need to ensure that on completion of your first operation you will perform your next process and not before that.
e.g: fn 1 -> read from queue (don't delete right now from queue) -> operation Completed if not perfrom again -> Delete from queue -> perform next operation.
You just have to make sure you read from queue and wait till you get response from DynamoDB.
Hope this helps.
I am a newbie in using socket.io in Node JS - however I have coded a client (web page) / server program to render some statistics data at client side.
The requirement is like – to render a box statistics (out of many). Since the user can open multiple browser windows - we have a scenario where one box data can be requested by many times:
http://www.tool.com?boxname=box1
As such I want to achieve spawning one job for multiple requests for same box. Below is the logic I have implemented to meet the requirement:
Client Side:
Establishes a connection to server creating a data channel:
socket.on(boxname.toLowerCase(), function (data){
}
So whenever there is a data in boxname event I receive, parse the data and render it.
Server Side
First call an expect script to copy a script to run within an infinite loop on a box.
On successful copying of the script in the box - invoke another expect script to start its execution:
exports.ServiceMonitor = function(boxName, res) {
Step 1.
I need to copy a script as many times request comes else I would not be able to enter ‘exit’ event of this spawned process where I start the script execution as mentioned below:
var child = spawn('./scripts/copyscriptonbox.sh' , [boxName.toLowerCase(), getURL(boxName)]);
In the later part of the code I keep adding box names to boxnames variable which is declared global. So on a new boxname request - I search for number of occurrences of boxname in boxnames variable. If the count is 1 or more it would mean to me that a script is already running on that box:
var noofbox = boxnames.split(boxName.toLowerCase()).length - 1;
child.on('exit', function (code) {
logger.info('child stream exit: ' + code);
if(code == 0)
{
boxNames += boxName.toLowerCase();
logger.info('Box name added: ' + boxNames);
res.render('boxpage', {}); //render a web page
io.sockets.on('connection', function (socket) {
logger.info('Connected to box :' + boxName);
if(noofbox <= 0)
schild = spawn('./scripts/boxmon.sh', [boxName.toLowerCase(), getURL(boxName)]);
schild.on('exit', function (code) {
logger.info('schild stream exit.');
});
schild.stderr.on('data', function (data) {
logger.info('stderr: ' + data);
});
schild.stdout.on('data', function (data) {
//generate response
});
socket.on('disconnect',function(){logger.info('Disconnect Killed');ServiceMonitorEnd(boxName.toLowerCase());});
});
}
});
}
The issue is that if in two browser window I access URL : www.tool.com?boxname=box1 - first time I get the log only once (Connected to box : box1) but second time I get the same logs 2 times where as I was expecting it to be one time - I mean as many request comes in after the first one the logs gets printed that many times – if 5 then log gets printed for 1(first time)+2 (second time)+3(third time)+4 (fourth time)+5 (fifth time)? I understand that when ‘connection’ event is called for x times then it enters that many times for each connection.
How can I make the 'connection' event on the socket.io once for each request only?
Use socket.once instead of socket.on, it is another EventEmitter like .on, that is emitted only once, the first time. Check the docs. But remember after that any such events will not be received by the client.