Why the function "onaddstream" is never called? - webrtc

Hello I followed this tutorial to create a simple webrtc example.
https://www.webrtc-experiment.com/docs/WebRTC-PeerConnection.html .
So look my JFFiddle:
https://jsfiddle.net/xzspquew/9/
and tell me please why I can't enter to the function onaddstream ? The console.log("this function is called") is neved called. Why ?
navigator.getUserMedia({audio:false, video:true}, success, error)
var pc = new RTCPeerConnection()
var pc2 = new RTCPeerConnection()
pc.onaddstream = function(event) {
console.log("this function is called")
var video2 = document.getElementById("video2")
video2.src = window.URL.createObjectURL(event.stream)
video2.play()
}
document.querySelector("#repondre").addEventListener('click', function repondre() {
var answer = prompt("Please enter your sdp remote offer");
console.log(answer)
pc2.setRemoteDescription(JSON.parse(answer))
pc2.createAnswer(successanswerrtc, errorrtc)
})
function successanswerrtc(answersdp) {
pc2.setLocalDescription(answersdp)
console.log(JSON.stringify(answersdp))
pc.setRemoteDescription(answersdp)
}
function sucessrtc(offersdp) {
pc.setLocalDescription(offersdp)
alert(JSON.stringify(offersdp))
console.log(JSON.stringify(offersdp))
}
function errorrtc(err) {
console.log("error" + err)
}
function success(stream) {
var video1 = document.getElementById("video1")
video1.src = window.URL.createObjectURL(stream)
video1.play()
pc.createOffer(sucessrtc, errorrtc)
}
function error() {
console.log("error")
}

That tutorial appears to be outdated. Perhaps https://webrtc.org/start/#demos-and-samples
According to MDN documentation, it has been deprecated:
https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/onaddstream
This property has been removed from the specification; you should now use RTCPeerConnection.ontrack to watch for track events instead. It is included here in order to help you adapt existing code and understand existing samples, which may not be up-to-date yet.

It looks you are trying with an outdated demo,
Try this demo from WebRTC official samples
In your fiddle you didn't handled the candidates & streams properly .
If you are making a call from pc to pc2, you need to add stream to pc by calling pc.addstream(stream) then pc2.onaddstream or pc2.onaddtrack method will triggered.
I updated your fiddle https://jsfiddle.net/8mchrc3v/1/

Related

HapiJS reply with readable stream

For one call, I am replying with a huge JSON object which sometimes causes the Node event loop to become blocked. As such, I'm using Big Friendly JSON package to stream JSON instead. My issue is I cannot figure out how to actually reply with the stream
My original code was simply
let searchResults = s3Access.getSavedSearch(guid)).Body;
searchResults = JSON.parse(searchResults.toString());
return reply(searchResults);
Works great but bogs down on huge payloads
I've tried things like, using the Big Friendly JSON package https://gitlab.com/philbooth/bfj
const stream = bfj.streamify(searchResults);
return reply(stream); // according to docs it's a readable stream
But then my browser complained about an empty response. I then tried to add the below to the reply, same result.
.header('content-encoding', 'json')
.header('Content-Length', stream.length);
I also tried return reply(null, stream); but that produced a ton of node errors
Is there some other way I need to organize this? My understanding was I could just reply a readable stream and Hapi would take care of it, but the response keeps showing up as empty.
Did you try to use h.response, here h is reply.
Example:
handler: async (request, h) => {
const { limit, sortBy, order } = request.query;
const queryString = {
where: { status: 1 },
limit,
order: [[sortBy, order]],
};
let userList = {};
try {
userList = await _getList(User, queryString);
} catch (e) {
// throw new Boom(e);
Boom.badRequest(i18n.__('controllers.user.fetchUser'), e);
}
return h.response(userList);
}

javascript function is not recognized as javascript code

I have the following javascript file MyService.js:
function(config) {
config.MyService = function(request) {
return call('classpath:path/to/my.feature#tag', request);
};
return config;
}
I load this js from my karate-config.js in order to reuse it from my feature files.
config = karate.callSingle('classpath:path/to/MyService.js', config);
It works as expected and I can call my.feature from any feature file. For example:
Given def res = call MyService myRequest
The problem appears when I try to add a new level to MyService.js function:
function(config) {
config.ApiOauthService = {
myCall : function(request) {
return call('classpath:path/to/my.feature#tag', request);
}
};
return config;
}
When I add the following code to my feature file:
Given def myCall = call MyService.myCall myRequest
I get the following error: "not a js function or feature file"
Do anybody know where is the problem? Is it possible to do what I am trying to do?
Thanks
Yes in Karate 0.9.3 onwards we have limited JS function nesting to only the top-level. You can find a full explanation in this comment.
So if you need JS function "name spacing" you can easily achieve this as per the documentation: https://github.com/intuit/karate#multiple-functions-in-one-file
And if you need more complex nesting, switch to using Java code where you can nest functions at any level.

How to securely store phone numbers in Twilio Functions?

I am using Twilio Functions. I wonder if the phone numbers stored in the Function's code are secure?
I am using code similar to that found here: https://support.twilio.com/hc/en-us/articles/223180548-How-Can-I-Stop-Receiving-or-Block-Incoming-Phone-Calls-#blacklistNumbers
Basically, it rejects numbers that on a blacklist of your choosing. The blacklist is in the Function's code itself.
Perhaps this is already secure. Forgive my misunderstanding.
The aforementioned code:
exports.handler = function(context, event, callback) {
// Listing all the blocked phone numbers, at the moment "+1(212)555-1234" and "+1(702)555-6789"
let blacklist = event.blacklist || [ "+12125551234", "+17025556789" ];
let twiml = new Twilio.twiml.VoiceResponse();
let blocked = true;
if (blacklist.length > 0) {
if (blacklist.indexOf(event.From) === -1) {
blocked = false;
}
}
if (blocked) {
twiml.reject();
}
else {
// if the caller's number is not blocked, redirecting to another TwiML which includes instructions for what to do
twiml.redirect("https://demo.twilio.com/docs/voice.xml");
}
callback(null, twiml);
};
Heyooo. Twilio Developer Evangelist here. 👋
I don't think you have to worry about the security of these numbers. But what you could do it to add the blacklist to the function configuration instead. This way you wouldn't have to change the function code whenever you want to add a new number to the blacklist.
These values below will be available in the context object that is passed into your function.
exports.handler = async function(context, event, callback) {
console.log(context.BLACKLIST); // 1212...
}

Prevent duplicate routes in express.js

Is there a nice way to prevent duplicate routes from being registered in express? I have a pretty large application with hundreds of routes across different files, and it gets difficult to know if I've already registered a certain route when I go to add a new one. For example, I'd like to throw an error when express gets to routes487.js:
File: routes1.js
var ctrl = require('../controllers/testctrl');
var auth = require('../libs/authentication');
module.exports = function (app) {
app.get('/hi', auth.getToken, ctrl.hi);
app.get('/there', auth.getToken, ctrl.there);
};
File: routes487.js
var ctrl = require('../controllers/testctrl487');
var auth = require('../libs/authentication');
module.exports = function (app) {
app.get('/hi', auth.getToken, ctrl.hi487);
};
You could try a custom solution by wrapping express methods with the validation. Consider the following modification to your express app:
// route-validation.js
module.exports = function (app) {
var existingRoutes = {}
, originalMethods = [];
// Returns true if the route is already registered.
function routeExists(verb, path) {
return existingRoutes[verb] &&
existingRoutes[verb].indexOf(path) > -1;
}
function registerRoute(verb, path) {
if (!existingRoutes[verb]) existingRoutes[verb] = [];
existingRoutes[verb].push(path);
}
// Return a new app method that will check repeated routes.
function validatedMethod(verb) {
return function() {
// If the route exists, app.VERB will throw.
if (routeExists(verb, arguments[0]) {
throw new Error("Can't register duplicate handler for path", arguments[0]);
}
// Otherwise, the route is saved and the original express method is called.
registerRoute(verb, arguments[0]);
originalMethods[verb].apply(app, arguments);
}
}
['get', 'post', 'put', 'delete', 'all'].forEach(function (verb) {
// Save original methods for internal use.
originalMethods[verb] = app[verb];
// Replace by our own route-validator methods.
app[verb] = validatedMethod(verb);
});
};
You just need to pass your app to this function after creation and duplicate route checking will be implemented. Note that you might need other "verbs" (OPTIONS, HEAD).
If you don't want to mess with express' methods (we don't know whether or how express itself or middleware modules will use them), you can use an intermediate layer (i.e., you actually wrap your app object instead of modifying its methods). I actually feel that would be a better solution, but I feel lazy to type it right now :)

Multiple image attachments to couchdb (nano) with Node.js Express 4.0 & formidable

I am trying to insert multiple images to couchdb via nano using express 4 and formidable. I can access and insert individual files without difficulty using formidable and nano, however, when I try to insert one file after another, I get conflict errors. I am very new to js and node, and I know my understanding of callbacks and asynchronous functions is limited. This is what I have at the moment. Any help would be greatly appreciated.
function uploadImage(req, res) {
var form = new formidable.IncomingForm(),
files = [],
fields = [];
uploadcount = 1;
form.on('field', function(field, value) {
fields.push([field, value]);
})
form.on('file', function(field, file) {
files.push([field, file]);
var docid = fields[0][1];
getrevision();
function getRevision(){
dbn.get(docid, { revs_info: true }, function(err,body, file){
if (!err) {
exrev = body._rev;
insertImage(exrev);
}else{
console.log(err);
}
});
}
function insertImage(exrevision){
var exrev = exrevision;
fs.readFile(file.path, function (err, data) {
if (err){
console.log(err);}else{
var imagename = docid + "_" + uploadcount + ".png";
dbn.attachment.insert(docid,imagename,data,'image/png',
{ rev: exrev }, function(err,body){
if (!err) {
uploadcount++;
}else{
console.log(err);
}
});
};
});
};
});
form.on('end', function() {
console.log('done');
res.redirect('/public/customise.html');
});
form.parse(req);
};
I found a solution by dumping the files first into a temporary directory, then proceeding to insert the files into couchdb via nano all within a single function. I couldn't find a way to pause the filestream to wait for the couchdb response, so this sequential method seems adequate.
This is a problem handling asynchronous calls. Because each attachment insert requires the doc's current rev number, you can't do the inserts in parallel. You must insert a new attachment only after you get a response from the the previous one.
You may use the promise and deferred mechanism to do this. But, I personally have solved a similar problem using a package called "async". In async, you can use async.eachSeries() to make these async calls in series.
Another point is about the revision number, you may just use the lighter weight db.head() function, instead of db.get(). The rev number is presented under the "etag" header. You can get the rev like this:
// get Rev number
db.head(bookId, function(err, _, headers) {
if (!err) {
var rev = eval(headers.etag);
// do whatever you need to do with the rev number
......
}
});
In addition, after each attachment insert, the response from couchdb will look something like this:
{"ok":true,"id":"b2aba1ed809a4395d850e65c3ff2130c","rev":"4-59d043853f084c18530c2a94b9a2caed"}
The rev property will give the new rev number which you may use for inserting to the next attachment.