Web App Push Notification, Unable to Push the notification on browser - node.js

I have been trying to push notification on my web app.
I have been following google's codelabs for assistance and I have been successful until I reached 'Handle a Push Event' part.
I did exactly what they had mentioned, where could I possibly go wrong?
I am new to this so please help and thanking everyone, who bothered to answer, in advance
My main script code is as follows:
'use strict';
const applicationServerPublicKey = 'BEEbOQcOmPNlAHvkHCdVGPehs3y45L-30_71yyrRbxNRp7Q3bCEGWoCnq5dxeiB2nwGWfTc5BOrbEWsU2FGXgtk';
const pushButton = document.querySelector('.js-push-btn');
let isSubscribed = false;
let swRegistration = null;
function urlB64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
if ('serviceWorker' in navigator && 'PushManager' in window) {
console.log('Service Worker and Push is supported');
navigator.serviceWorker.register('sw.js')
.then(function(swReg) {
console.log('Service Worker is registered', swReg);
swRegistration = swReg;
})
.catch(function(error) {
console.error('Service Worker Error', error);
});
} else {
console.warn('Push messaging is not supported');
pushButton.textContent = 'Push Not Supported';
}
function initializeUI() {
pushButton.addEventListener('click', function() {
pushButton.disabled = true;
if (isSubscribed) {
// TODO: Unsubscribe user
} else {
subscribeUser();
}
});
// Set the initial subscription value
swRegistration.pushManager.getSubscription()
.then(function(subscription) {
isSubscribed = !(subscription === null);
if (isSubscribed) {
console.log('User IS subscribed.');
} else {
console.log('User is NOT subscribed.');
}
updateBtn();
});
}
function updateBtn() {
if (Notification.permission === 'denied') {
pushButton.textContent = 'Push Messaging Blocked.';
pushButton.disabled = true;
updateSubscriptionOnServer(null);
return;
}
if (isSubscribed) {
pushButton.textContent = 'Disable Push Messaging';
} else {
pushButton.textContent = 'Enable Push Messaging';
}
pushButton.disabled = false;
}
function subscribeUser() {
const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
swRegistration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: applicationServerKey
})
.then(function(subscription) {
console.log('User is subscribed.');
updateSubscriptionOnServer(subscription);
isSubscribed = true;
updateBtn();
})
.catch(function(err) {
console.log('Failed to subscribe the user: ', err);
updateBtn();
});
}
function updateSubscriptionOnServer(subscription) {
// TODO: Send subscription to application server
const subscriptionJson = document.querySelector('.js-subscription-json');
const subscriptionDetails =
document.querySelector('.js-subscription-details');
if (subscription) {
subscriptionJson.textContent = JSON.stringify(subscription);
subscriptionDetails.classList.remove('is-invisible');
} else {
subscriptionDetails.classList.add('is-invisible');
}
}
navigator.serviceWorker.register('sw.js')
.then(function(swReg) {
console.log('Service Worker is registered', swReg);
swRegistration = swReg;
initializeUI();
})
My sw.js code is
'use strict';
self.addEventListener('push', function(event) {
console.log('[Service Worker] Push Received.');
console.log(`[Service Worker] Push had this data: "${event.data.text()}"`);
const title = 'Push Codelab';
const options = {
body: 'Yay it works.',
icon: 'images/icon.png',
badge: 'images/badge.png'
};
event.waitUntil(self.registration.showNotification(title, options));
});
I am getting the following error message in my console :
Service Worker termination by a timeout timer was canceled because DevTools is attached.

'use strict';
const applicationServerPublicKey = 'BKqJnZ7e-r7DMOqpx2mm-BCWDCm1Urvt2KnwwmFe7v5QEfMMl139SlNGi6T6FSUmcNVJhXEI6_uLiauw1AFuMJc';
//BKqJnZ7e+r7DMOqpx2mm+BCWDCm1Urvt2KnwwmFe7v5QEfMMl139SlNGi6T6FSUmcNVJhXEI6/uLiauw1AFuMJc=
const pushButton = document.querySelector('.js-push-btn');
let isSubscribed = false;
let swRegistration = null;
function urlB64ToUint8Array(base64String)
{
const padding = '='.repeat((4 - base64String.length % 4) % 4);
//console.log(padding + base64String.length);
const base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
const rawData = window.atob(base64);
//console.log(base64);
//console.log(rawData);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i)
{
outputArray[i] = rawData.charCodeAt(i);
}
console.log(outputArray);
return outputArray;
}
//1
if ('serviceWorker' in navigator && 'PushManager' in window)
{
console.log('Service Worker and Push is supported');
navigator.serviceWorker.register('sw.js').then
(
function(swReg)
{
//console.log(swReg);
console.log('Service Worker is registered', swReg);
swRegistration = swReg;
//console.log(swRegistration);
}
)
.catch
(
function(error)
{
console.error('Service Worker Error', error);
}
);
}
else
{
console.warn('Push messaging is not supported');
pushButton.textContent = 'Push Not Supported';
}
//2
function updateBtn()
{
if (Notification.permission === 'denied')
{
pushButton.textContent = 'Push Messaging Blocked.';
pushButton.disabled = true;
updateSubscriptionOnServer(null);
return;
}
if (isSubscribed)
{
pushButton.textContent = 'Disable Push Messaging';
}
else
{
pushButton.textContent = 'Enable Push Messaging';
}
pushButton.disabled = false;
}
navigator.serviceWorker.register('sw.js').then
(
function(swReg)
{
console.log('Service Worker is registered', swReg);
swRegistration = swReg;
initializeUI();
}
)
//3
function initializeUI()
{
pushButton.addEventListener
(
'click', function()
{
pushButton.disabled = true;
if (isSubscribed)
{
unsubscribeUser();
}
else
{
subscribeUser();
}
}
);
// Set the initial subscription value
swRegistration.pushManager.getSubscription().then
(
function(subscription)
{
isSubscribed = !(subscription === null);
updateSubscriptionOnServer(subscription);
if (isSubscribed)
{
console.log('User IS subscribed.');
}
else
{
console.log('User is NOT subscribed.');
}
updateBtn();
}
);
}
//4
function subscribeUser()
{
const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
swRegistration.pushManager.subscribe
(
{
userVisibleOnly: true,
applicationServerKey: applicationServerKey
}
)
.then
(
function(subscription)
{
console.log('User is subscribed.');
updateSubscriptionOnServer(subscription);
isSubscribed = true;
updateBtn();
}
)
.catch
(
function(err)
{
console.log('Failed to subscribe the user: ', err);
updateBtn();
}
);
}
//5
function updateSubscriptionOnServer(subscription)
{
// TODO: Send subscription to application server
const subscriptionJson = document.querySelector('.js-subscription-json');
const subscriptionDetails = document.querySelector('.js-subscription-details');
if (subscription)
{
subscriptionJson.textContent = JSON.stringify(subscription);
subscriptionDetails.classList.remove('is-invisible');
}
else
{
subscriptionDetails.classList.add('is-invisible');
}
}
//6
function unsubscribeUser() {
swRegistration.pushManager.getSubscription()
.then(function(subscription) {
if (subscription) {
return subscription.unsubscribe();
}
})
.catch(function(error) {
console.log('Error unsubscribing', error);
})
.then(function() {
updateSubscriptionOnServer(null);
console.log('User is unsubscribed.');
isSubscribed = false;
updateBtn();
});
}

Related

nodejs/express, Controller send the response before to get the result of function setInterval

the problem is :
In Controller, the response is send before the result of condition into function setInterval
Steps :
Controller run function setInterval
Then send the response to frontend with res.status.json
The function setInterval run
condition of setInterval work and finish
setInterval don't return the resultto controller
the controller have already sent a res...
import checkHealth from "./checkHealth.js";
async function checkHealthInterval(labelData) {
console.log("labelData==>", labelData);
let resultInterval = { health: "", message: "" };
let i = 1;
let interval;
interval = await setInterval(async () => {
let healthCheckers = await checkHealth();
let healthCheckerStatus;
if (labelData== "example1") {
healthCheckerStatus = healthCheckers.statusInstanceGlobal;
console.log(
"healthCheckerStatus value from tenant1 : ",
healthCheckerStatus
);
} else {
healthCheckerStatus = healthCheckers.statusWam1Wam2;
console.log(
"healthCheckerStatus value from tenant2 : ",
healthCheckerStatus
);
}
i++;
if (healthCheckerStatus !== true && i > 36) {
clearInterval(interval);
console.log("VMs are UNHEALTHY in the end of interval or before the end");
this.isProcessing = false;
throw new ApiError(
500,
"VMs are UNHEALTHY in the end of interval or before the end"
);
} else if (healthCheckerStatus == true) {
clearInterval(interval);
console.log(
`VMs ${labelData} are HEALTHY and successfully started!`
);
resultInterval.health = "healthy";
resultInterval.message = "VMs are successfully started!";
console.log("resultInterval into interval===>", resultInterval);
return resultInterval
}
}, 10000);
console.log("Script interval is running to check health");
return interval
}
export { checkHealthInterval };
getStartVms = async (req, res, next) => {
console.log("You asked to start VMs: starting VMs");
try {
this.isProcessing = true;
const responseStart = await this.instanceService.startInstances();
// use interval to checkHealth of Vms with import function checkHealth()
const resultInterval = await checkHealthInterval(responseStart?.labelData);
res.status(200).json({
health: "healthy",
message: "VMs are successfully started!",
});
this.isProcessing = false;
io.emit("processChanged", this.isProcessing);
} catch (err) {
this.isProcessing = false;
io.emit("processChanged", this.isProcessing);
next(err);
}
};

Node.js webRTC screen shareing

I have got problem with webRTC screen sharing. When one person shares his screen another person can`t see shared screen stream, and asks him for again sharing screen.I am useing node.js express server with socket.io. I am useing Google chrome. It requires HTTPS connection if it is not local.
This is web application code`
(function() {
const socket = io.connect(window.location.origin);
const localVideo = document.querySelector('.localVideo');
const remoteVideos = document.querySelector('.remoteVideos');
const peerConnections = {};
var url_string =window.location.href
var url = new URL(url_string);
var de = url.searchParams.get("key");
let room = de
let getUserMediaAttempts = 5;
let gettingUserMedia = false;
let getdisplaymedia=true;
const config = {
'iceServers': [{
'urls': ['stun:stun.l.google.com:19302']
}]
};
/** #type {MediaStreamConstraints} */
const constraints = {
audio: true,
video: { facingMode: "user" }
};
socket.on('bye', function(id) {
handleRemoteHangup(id);
});
if (room && !!room) {
socket.emit('join', room);
}
window.onunload = window.onbeforeunload = function() {
socket.close();
};
socket.on('ready', function (id) {
if (!(localVideo instanceof HTMLVideoElement) || !localVideo.srcObject) {
return;
}
const peerConnection = new RTCPeerConnection(config);
peerConnections[id] = peerConnection;
if (localVideo instanceof HTMLVideoElement) {
peerConnection.addStream(localVideo.srcObject);
}
peerConnection.createOffer()
.then(sdp => peerConnection.setLocalDescription(sdp))
.then(function () {
socket.emit('offer', id, peerConnection.localDescription);
});
peerConnection.onaddstream = event => handleRemoteStreamAdded(event.stream, id);
peerConnection.onicecandidate = function(event) {
if (event.candidate) {
socket.emit('candidate', id, event.candidate);
}
};
});
socket.on('offer', function(id, description) {
const peerConnection = new RTCPeerConnection(config);
peerConnections[id] = peerConnection;
if (localVideo instanceof HTMLVideoElement) {
peerConnection.addStream(localVideo.srcObject);
}
peerConnection.setRemoteDescription(description)
.then(() => peerConnection.createAnswer())
.then(sdp => peerConnection.setLocalDescription(sdp))
.then(function () {
socket.emit('answer', id, peerConnection.localDescription);
});
peerConnection.onaddstream = event => handleRemoteStreamAdded(event.stream, id);
peerConnection.onicecandidate = function(event) {
if (event.candidate) {
socket.emit('candidate', id, event.candidate);
}
};
});
socket.on('candidate', function(id, candidate) {
peerConnections[id].addIceCandidate(new RTCIceCandidate(candidate))
.catch(e => console.error(e));
});
socket.on('answer', function(id, description) {
peerConnections[id].setRemoteDescription(description);
});
function getUserMediaSuccess(stream) {
gettingUserMedia = false;
if (localVideo instanceof HTMLVideoElement) {
!localVideo.srcObject && (localVideo.srcObject = stream);
}
socket.emit('ready');
}
function handleRemoteStreamAdded(stream, id) {
const remoteVideo = document.createElement('video');
remoteVideo.srcObject = stream;
remoteVideo.setAttribute("id", id.replace(/[^a-zA-Z]+/g, "").toLowerCase());
remoteVideo.setAttribute("playsinline", "true");
remoteVideo.setAttribute("autoplay", "true");
remoteVideos.appendChild(remoteVideo);
if (remoteVideos.querySelectorAll("video").length === 1) {
remoteVideos.setAttribute("class", "one remoteVideos");
} else {
remoteVideos.setAttribute("class", "remoteVideos");
}
}
function getUserMediaError(error) {
console.error(error);
gettingUserMedia = false;
(--getUserMediaAttempts > 0) && setTimeout(getUserMediaDevices, 1000);
}
function getUserMediaDevices() {
if (localVideo instanceof HTMLVideoElement) {
if (localVideo.srcObject) {
getUserMediaSuccess(localVideo.srcObject);
} else if (!gettingUserMedia && !localVideo.srcObject) {
gettingUserMedia = true;
navigator.mediaDevices.getDisplayMedia(constraints)
.then(getUserMediaSuccess)
.catch(getUserMediaError);
}
}
}
function handleRemoteHangup(id) {
peerConnections[id] && peerConnections[id].close();
delete peerConnections[id];
document.querySelector("#" + id.replace(/[^a-zA-Z]+/g, "").toLowerCase()).remove();
if (remoteVideos.querySelectorAll("video").length === 1) {
remoteVideos.setAttribute("class", "one remoteVideos");
} else {
remoteVideos.setAttribute("class", "remoteVideos");
}
}
getUserMediaDevices();
})();
This is node.js code`
const credentials = require('./credentials');
const express = require('express');
const app = express();
let server;
let port;
if (credentials.key && credentials.cert) {
const https = require('https');
server = https.createServer(credentials, app);
port = 443;
} else {
const http = require('http');
server = http.createServer(app);
port = 1517;
}
const io = require('socket.io')(server);
const RoomService = require('./RoomService')(io);
io.sockets.on('connection', RoomService.listen);
io.sockets.on('error', e => console.log(e));
app.use(express.static(__dirname + '/public'));
app.get('*', function(req, res) {
res.sendFile(${__dirname}/public/index.html);
});
server.listen(port, () => console.log(Server is running on port ${port}));
ok man this is fixed code you can use yuu need just stream getDisplayMedia value
(function() {
const socket = io.connect(window.location.origin);
const localVideo = document.querySelector('.localVideo');
const remoteVideos = document.querySelector('.remoteVideos');
const peerConnections = {};
var url_string =window.location.href
var url = new URL(url_string);
var de = url.searchParams.get("key");
let room = de
let getUserMediaAttempts = 5;
let gettingUserMedia = false;
let getdisplaymedia=true;
/** #type {RTCConfiguration} */
const config = {
'iceServers': [{
'urls': ['stun:stun.l.google.com:19302']
}]
};
/** #type {MediaStreamConstraints} */
const constraints = {
audio: true,
video: { facingMode: "user" }
};
socket.on('full', function(room) {
alert('Room ' + room + ' is full');
});
socket.on('bye', function(id) {
handleRemoteHangup(id);
});
if (room && !!room) {
socket.emit('join', room);
}
window.onunload = window.onbeforeunload = function() {
socket.close();
};
socket.on('ready', function (id) {
if (!(localVideo instanceof HTMLVideoElement) || !localVideo.srcObject) {
return;
}
const peerConnection = new RTCPeerConnection(config);
peerConnections[id] = peerConnection;
if (localVideo instanceof HTMLVideoElement) {
peerConnection.addStream(localVideo.srcObject);
}
peerConnection.createOffer()
.then(sdp => peerConnection.setLocalDescription(sdp))
.then(function () {
socket.emit('offer', id, peerConnection.localDescription);
});
peerConnection.onaddstream = event => handleRemoteStreamAdded(event.stream, id);
peerConnection.onicecandidate = function(event) {
if (event.candidate) {
socket.emit('candidate', id, event.candidate);
}
};
});
socket.on('offer', function(id, description) {
const peerConnection = new RTCPeerConnection(config);
peerConnections[id] = peerConnection;
if (localVideo instanceof HTMLVideoElement) {
peerConnection.addStream(localVideo.srcObject);
}
peerConnection.setRemoteDescription(description)
.then(() => peerConnection.createAnswer())
.then(sdp => peerConnection.setLocalDescription(sdp))
.then(function () {
socket.emit('answer', id, peerConnection.localDescription);
});
peerConnection.onaddstream = event => handleRemoteStreamAdded(event.stream, id);
peerConnection.onicecandidate = function(event) {
if (event.candidate) {
socket.emit('candidate', id, event.candidate);
}
};
});
socket.on('candidate', function(id, candidate) {
peerConnections[id].addIceCandidate(new RTCIceCandidate(candidate))
.catch(e => console.error(e));
});
socket.on('answer', function(id, description) {
peerConnections[id].setRemoteDescription(description);
});
function getUserMediaSuccess(stream) {
gettingUserMedia = false;
if (localVideo instanceof HTMLVideoElement) {
!localVideo.srcObject && (localVideo.srcObject = stream);
}
socket.emit('ready');
}
function handleRemoteStreamAdded(stream, id) {
const remoteVideo = document.createElement('video');
remoteVideo.srcObject = stream;
remoteVideo.setAttribute("id", id.replace(/[^a-zA-Z]+/g, "").toLowerCase());
remoteVideo.setAttribute("playsinline", "true");
remoteVideo.setAttribute("autoplay", "true");
remoteVideos.appendChild(remoteVideo);
if (remoteVideos.querySelectorAll("video").length === 1) {
remoteVideos.setAttribute("class", "one remoteVideos");
} else {
remoteVideos.setAttribute("class", "remoteVideos");
}
}
function getUserMediaError(error) {
console.error(error);
gettingUserMedia = false;
(--getUserMediaAttempts > 0) && setTimeout(getUserMediaDevices, 1000);
}
function getUserMediaDevices() {
var constraints = { audio: true, video: { width: 1280, height: 720 } };
navigator.mediaDevices.getDisplayMedia(constraints)
.then(function(mediaStream) {
var video = document.querySelector('video');
video.srcObject = mediaStream;
video.onloadedmetadata = function(e) {
video.play();
getUserMediaSuccess(video.srcObject)
};
})
.catch(function(err) { console.log(err.name + ": " + err.message); }); // always check for errors at the end.
}
function handleRemoteHangup(id) {
peerConnections[id] && peerConnections[id].close();
delete peerConnections[id];
document.querySelector("#" + id.replace(/[^a-zA-Z]+/g, "").toLowerCase()).remove();
if (remoteVideos.querySelectorAll("video").length === 1) {
remoteVideos.setAttribute("class", "one remoteVideos");
} else {
remoteVideos.setAttribute("class", "remoteVideos");
}
}
getUserMediaDevices();
})();

Need to add try catch block

I am new to nodejs so below is my code, I need to add try-catch blocks for my below code need some help to do this because new to this things, below is my websocket code newly created I need to add try-catch blocks for this , please help me out anyone
var WebSocket = require('ws');
//var Stomp = require('stompjs');
function CustomWebSocketListener(config) {
RED.nodes.createNode(this,config);
var node = this;
node.on('input', function(msg) {
let temp =msg.payload;
let urllist = temp.url;
let urls=[]
if(global.websocket!=null || global.websocket!=undefined){
let connections=global.websocket;
console.log("global")
if(global.isAccessTokenExpired){
for(let k in connections) {
connections[k].close();
connections[k].reconnect=false
console.log('connection closed:::');
}
urls=urllist;
}
else{
for(let i=0;i<urllist.length;i++){
let group=urllist[i].split("/")[7].split("?");
if(!connections[group[0]]){
urls.push(urllist[i])
}
}
}
}
else{
urls=urllist;
}
console.log("urls.length::::"+urls.length)
if(urls.length > 0){
for(let i=0;i<urls.length;i++){
console.log(':::::::for loop:::::::')
console.log('url----'+urls[i])
function connect(urlIndex) {
let ws;
if(urlIndex!=undefined||urlIndex!=null){
ws = new WebSocket(urls[urlIndex]);
}
else{
ws = new WebSocket(urls[i]);
}
ws.index=i;
ws.reconnect=true;
ws.onopen = function() {
};
ws.onmessage = function(e) {
console.log('Message:', e.data);
console.log('Socket is closed. Reconnect will be attempted in 30 second.', e.reason);
setTimeout(function() {
console.log("onclose ----ws reconnect"+ws.reconnect)
if(ws.reconnect){
console.log("inside if reconnect")
connect(ws.index);
}
}, 30000);
};
ws.onerror = function(err) {
console.error('Socket encountered error: ', err.message, 'Closing socket');
ws.close();
};
if(global.websocket==null || global.websocket==undefined){
global.websocket={};
console.log(global.websocket)
global.websocket[urls[i]]=ws;
}
else{
global.websocket[urls[i]]=ws;
}
}
connect();
}
}
});
}
RED.nodes.registerType("custom-websocketlistener",CustomWebSocketListener);
}
Thanks for anyone who would help me out with this
you can directly use where you want like this...
try{
//whatever you want
}
catch(e){
//whatever you want
}
In your code you can use like this
try {
RED.nodes.createNode(this, config)
var node = this
node.on('input', function(msg) {
let temp = msg.payload
let urllist = temp.url
let urls = []
if (global.websocket != null || global.websocket != undefined) {
let connections = global.websocket
console.log('global')
if (global.isAccessTokenExpired) {
for (let k in connections) {
connections[k].close()
connections[k].reconnect = false
console.log('connection closed:::')
}
urls = urllist
} else {
for (let i = 0; i < urllist.length; i++) {
let group = urllist[i].split('/')[7].split('?')
if (!connections[group[0]]) {
urls.push(urllist[i])
}
}
}
} else {
urls = urllist
}
console.log('urls.length::::' + urls.length)
if (urls.length > 0) {
for (let i = 0; i < urls.length; i++) {
console.log(':::::::for loop:::::::')
console.log('url----' + urls[i])
function connect(urlIndex) {
let ws
if (urlIndex != undefined || urlIndex != null) {
ws = new WebSocket(urls[urlIndex])
} else {
ws = new WebSocket(urls[i])
}
ws.index = i
ws.reconnect = true
ws.onopen = function() {}
ws.onmessage = function(e) {
console.log('Message:', e.data)
console.log('Socket is closed. Reconnect will be attempted in 30 second.', e.reason)
setTimeout(function() {
console.log('onclose ----ws reconnect' + ws.reconnect)
if (ws.reconnect) {
console.log('inside if reconnect')
connect(ws.index)
}
}, 30000)
}
ws.onerror = function(err) {
console.error('Socket encountered error: ', err.message, 'Closing socket')
ws.close()
}
if (global.websocket == null || global.websocket == undefined) {
global.websocket = {}
console.log(global.websocket)
global.websocket[urls[i]] = ws
} else {
global.websocket[urls[i]] = ws
}
}
connect()
}
}
})
} catch (e) {
console.log(e)
}
}

WebRTC video only works when computers share same connection

So I have set up a web RTC connection, nearly fully understand the steps and mechanisms involved and have a test out on the web with a full SSL certificate (so I can use it on chrome) but It doesn't ever seem to work with computers that are not under the same wireless connection/router.
In my test I have logged that there are ICE candidates generated and that the two browsers are communicating but I get no video feed except for when the two trying to communicate are under the same connection.
Browser Side to set up webRTC:
var socket = io.connect();
var isChannelReady;
var isInitiator = false;
var isStarted = false;
var localStream;
var pc;
var remoteStream;
var turnReady;
var pc_config = {'iceServers': [{'url': 'stun:stun.l.google.com:19302'}]};
var pc_constraints = {'optional': [{'DtlsSrtpKeyAgreement': true}]};
// Set up audio and video regardless of what devices are present.
// var sdpConstraints = {'mandatory': {
// 'OfferToReceiveAudio':true,
// 'OfferToReceiveVideo':true }};
var sdpConstraints = {
optional: [],
'mandatory': {
'OfferToReceiveAudio': true,
'OfferToReceiveVideo': true
}
};
function sendMessage(message){
console.log('Client sending message: ', message);
// if (typeof message === 'object') {
// message = JSON.stringify(message);
// }
socket.emit('message', message);
}
socket.on('message', function (message){
console.log('Client received message:', message);
if (message === 'got user media') {
maybeStart();
} else if (message.type === 'offer') {
if (!isInitiator && !isStarted) {
maybeStart();
}
pc.setRemoteDescription(new RTCSessionDescription(message), function(){doAnswer()});
} else if (message.type === 'answer' && isStarted) {
pc.setRemoteDescription(new RTCSessionDescription(message));
} else if (message.type === 'candidate' && isStarted) {
var candidate = new RTCIceCandidate({
sdpMLineIndex: message.label,
candidate: message.candidate
});
pc.addIceCandidate(candidate);
} else if (message === 'bye' && isStarted) {
handleRemoteHangup();
}
});
////////////////////////////////////////////////////
var localVideo = document.getElementById('localVideo');
var remoteVideo = document.getElementById('remoteVideo');
function handleUserMedia(stream) {
console.log('Adding local stream.');
console.log(localVideo);
localVideo.src = window.URL.createObjectURL(stream);
localStream = stream;
sendMessage('got user media');
if (isInitiator) {
maybeStart();
}
}
function handleUserMediaError(error){
console.log('getUserMedia error: ', error);
}
// window.onload = function () {
// var localVideo = document.getElementById('localVideo');
// var remoteVideo = document.getElementById('mehh');
// }
var constraints = {video: true};
navigator.getUserMedia(constraints, handleUserMedia, handleUserMediaError);
console.log('Getting user media with constraints', constraints);
if (location.hostname != "localhost") {
requestTurn('https://computeengineondemand.appspot.com/turn?username=41784574&key=4080218913');
}
function maybeStart() {
if (!isStarted && typeof localStream != 'undefined' && isChannelReady) {
createPeerConnection();
pc.addStream(localStream);
isStarted = true;
console.log('isInitiator', isInitiator);
if (isInitiator) {
doCall();
}
}
}
window.onbeforeunload = function(e){
sendMessage('bye');
}
/////////////////////////////////////////////////////////
function createPeerConnection() {
try {
pc = new RTCPeerConnection(null);
pc.onicecandidate = handleIceCandidate;
pc.onaddstream = handleRemoteStreamAdded;
pc.onremovestream = handleRemoteStreamRemoved;
console.log('Created RTCPeerConnnection');
} catch (e) {
console.log('Failed to create PeerConnection, exception: ' + e.message);
alert('Cannot create RTCPeerConnection object.');
return;
}
}
function handleIceCandidate(event) {
console.log('handleIceCandidate event: ', event);
if (event.candidate) {
sendMessage({
type: 'candidate',
label: event.candidate.sdpMLineIndex,
id: event.candidate.sdpMid,
candidate: event.candidate.candidate});
} else {
console.log('End of candidates.');
}
}
function handleRemoteStreamAdded(event) {
console.log('Remote stream added.');
remoteVideo.src = window.URL.createObjectURL(event.stream);
remoteStream = event.stream;
}
function handleCreateOfferError(event){
console.log('createOffer() error: ', e);
}
function doCall() {
console.log('Sending offer to peer');
pc.createOffer(setLocalAndSendMessage, handleCreateOfferError);
}
function doAnswer() {
console.log('Sending answer to peer.');
pc.createAnswer(setLocalAndSendMessage, function(err){if(err) throw err;}, sdpConstraints);
}
function setLocalAndSendMessage(sessionDescription) {
// Set Opus as the preferred codec in SDP if Opus is present.
sessionDescription.sdp = preferOpus(sessionDescription.sdp);
pc.setLocalDescription(sessionDescription);
console.log('setLocalAndSendMessage sending message' , sessionDescription);
sendMessage(sessionDescription);
}
function requestTurn(turn_url) {
var turnExists = false;
for (var i in pc_config.iceServers) {
if (pc_config.iceServers[i].url.substr(0, 5) === 'turn:') {
turnExists = true;
turnReady = true;
break;
}
}
if (!turnExists) {
console.log('Getting TURN server from ', turn_url);
// No TURN server. Get one from computeengineondemand.appspot.com:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (xhr.readyState === 4 && xhr.status === 200) {
var turnServer = JSON.parse(xhr.responseText);
console.log('Got TURN server: ', turnServer);
pc_config.iceServers.push({
'url': 'turn:' + turnServer.username + '#' + turnServer.turn,
'credential': turnServer.password
});
turnReady = true;
}
};
xhr.open('GET', turn_url, true);
xhr.send();
}
}
function handleRemoteStreamAdded(event) {
console.log('Remote stream added.');
remoteVideo.src = window.URL.createObjectURL(event.stream);
remoteStream = event.stream;
}
function handleRemoteStreamRemoved(event) {
console.log('Remote stream removed. Event: ', event);
}
function hangup() {
console.log('Hanging up.');
stop();
sendMessage('bye');
}
function handleRemoteHangup() {
// console.log('Session terminated.');
// stop();
// isInitiator = false;
}
function stop() {
isStarted = false;
// isAudioMuted = false;
// isVideoMuted = false;
pc.close();
pc = null;
}
///////////////////////////////////////////
// Set Opus as the default audio codec if it's present.
function preferOpus(sdp) {
var sdpLines = sdp.split('\r\n');
var mLineIndex;
// Search for m line.
for (var i = 0; i < sdpLines.length; i++) {
if (sdpLines[i].search('m=audio') !== -1) {
mLineIndex = i;
break;
}
}
if (mLineIndex === null || mLineIndex === undefined) {
return sdp;
}
// If Opus is available, set it as the default in m line.
for (i = 0; i < sdpLines.length; i++) {
if (sdpLines[i].search('opus/48000') !== -1) {
var opusPayload = extractSdp(sdpLines[i], /:(\d+) opus\/48000/i);
if (opusPayload) {
sdpLines[mLineIndex] = setDefaultCodec(sdpLines[mLineIndex], opusPayload);
}
break;
}
}
// Remove CN in m line and sdp.
sdpLines = removeCN(sdpLines, mLineIndex);
sdp = sdpLines.join('\r\n');
return sdp;
}
function extractSdp(sdpLine, pattern) {
var result = sdpLine.match(pattern);
return result && result.length === 2 ? result[1] : null;
}
// Set the selected codec to the first in m line.
function setDefaultCodec(mLine, payload) {
var elements = mLine.split(' ');
var newLine = [];
var index = 0;
for (var i = 0; i < elements.length; i++) {
if (index === 3) { // Format of media starts from the fourth.
newLine[index++] = payload; // Put target payload to the first.
}
if (elements[i] !== payload) {
newLine[index++] = elements[i];
}
}
return newLine.join(' ');
}
// Strip CN from sdp before CN constraints is ready.
function removeCN(sdpLines, mLineIndex) {
console.log(sdpLines[mLineIndex])
var mLineElements = sdpLines[mLineIndex].split(' ');
// Scan from end for the convenience of removing an item.
for (var i = sdpLines.length-1; i >= 0; i--) {
var payload = extractSdp(sdpLines[i], /a=rtpmap:(\d+) CN\/\d+/i);
if (payload) {
var cnPos = mLineElements.indexOf(payload);
if (cnPos !== -1) {
// Remove CN payload from m line.
mLineElements.splice(cnPos, 1);
}
// Remove CN line in sdp
sdpLines.splice(i, 1);
}
}
sdpLines[mLineIndex] = mLineElements.join(' ');
return sdpLines;
}
/////////////////////////////////////////////
room = prompt("Enter room name:");
var socket = io.connect();
if (room !== '') {
console.log('Create or join room', room);
socket.emit('create or join', room);
}
socket.on('created', function (room){
console.log('Created room ' + room);
isInitiator = true;
});
socket.on('full', function (room){
console.log('Room ' + room + ' is full');
});
socket.on('join', function (room){
console.log('Another peer made a request to join room ' + room);
console.log('This peer is the initiator of room ' + room + '!');
isChannelReady = true;
});
socket.on('joined', function (room){
console.log('This peer has joined room ' + room);
isChannelReady = true;
});
socket.on('log', function (array){
console.log.apply(console, array);
});
////////////////////////////////////////////////
And here is everything on the server side pertaining to webRTC (using socket io):
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
var io = require('socket.io').listen(server);
io.sockets.on('connection', function (socket){
console.log('connected');
// convenience function to log server messages on the client
function log(){
var array = [">>> Message from server: "];
for (var i = 0; i < arguments.length; i++) {
array.push(arguments[i]);
}
socket.emit('log', array);
}
socket.on('message', function (message) {
log('Got message:', message);
// for a real app, would be room only (not broadcast)
socket.broadcast.emit('message', message);
});
socket.on('create or join', function (room) {
//io.sockets.clients(room)
//io.of('/').in(room).clients
//io.sockets.adapter.rooms[room]
var numClients;
var ish = io.sockets.adapter.rooms[room];
(ish === undefined) ? numClients = 0 : numClients = ish.length
log('Room ' + room + ' has ' + numClients + ' client(s)');
log('Request to create or join room ' + room);
if (numClients === 0){
socket.join(room);
socket.emit('created', room);
} else if (numClients === 1) {
io.sockets.in(room).emit('join', room);
socket.join(room);
socket.emit('joined', room);
} else { // max two clients
socket.emit('full', room);
}
socket.emit('emit(): client ' + socket.id + ' joined room ' + room);
socket.broadcast.emit('broadcast(): client ' + socket.id + ' joined room ' + room);
});
});
I simply can't find any errors that prevent the streams from being sent...
More than willing to do a private chat so I can get moving on my project.

wit.ai : sessionid undefined in my runActions function

I am writing my first apps with wit.ai using a node.js backend. I found some posts here similar to my question, but not really the answer :
I use a socket.io to communicate with my node script.
The two relevant parts of my node are :
io.sockets.on('connection', function (socket) {
socket.on('message',
function(data) {
var json = JSON.parse(data);
var sid = json['sessionid'];
console.log("Received on sid " + sid);
if (_sessions[sid] == undefined) {
_sessions[sid] = {};
_sessions[sid].context = {};
}
_sessions[sid].socket = socket;
client.runActions(sid, json['text'], _sessions[sid].context, 30)
.then((context) => {
_sessions[sid].context = context;
}
)
.catch((err) =>
{
console.error('Oops! Got an error from Wit: ', err.stack || err);
}
);
}
);
}
);
========
const actions = {
send(request, response) {
const {sessionId, context, entities} = request;
const {text, quickreplies} = response;
return new Promise(function(resolve, reject) {
var session = _sessions[sessionId];
console.log("-------------------------------");
console.dir(context);
console.log("-------------------------------");
session.socket.emit("message", JSON.stringify(response));
return resolve();
});
},
gettaxi ({sessionid, context, text, entities}) {
return new Promise(function(resolve, reject) {
console.log(`Session ${sessionid} received ${text}`);
var quand = firstEntityValue(entities, "quand");
if (!quand && context['quand'] != undefined) quand = context['quand'];
var depart = firstEntityValue(entities, "depart");
var arrivee = firstEntityValue(entities, "arrivee");
if (depart) {
console.log("Found depart");
context.depart = depart;
delete context.missing_depart;
}
else {
context.missing_depart = true;
}
if (arrivee) {
console.log("Found arrivee");
context.arrivee = arrivee;
delete context.missing_arrivee;
}
else {
context.missing_arrivee = true;
}
console.dir(context);
if (quand) {
console.log("Found quand");
context.quand = quand;
delete context.missing_quand;
}
else {
context.missing_quand = true;
}
return resolve(context);
}
);
},
};
All is working rather good, except than my gettaxi receives a undefined sessionid.
It's not the case for the send function that receives the correct sessionid.
What am I doing wrong ?

Resources