AWS Lambda (NodeJS) does not log to cloudwatch - node.js

I'm trying to log my lambda app after following serverless-next.js because of the issue where I can't go to the root of my file. So basically I'm deploying nextJS app in AWS through lambda#edge, s3, and cloudfront.
I'm new to AWS so I'm not really sure how to debug this thing at all. I assume traditional console.log in my lambda where every request comes in would log it in the cloudwatch. I also made sure that I deployed my lambda to my cloud front
Here's the code:
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.handler = void 0;
const prerender_manifest_json_1 = __importDefault(require("./prerender-manifest.json"));
const manifest_json_1 = __importDefault(require("./manifest.json"));
const next_aws_cloudfront_1 = __importDefault(require("#sls-next/next-aws-cloudfront"));
const addS3HostHeader = (req, s3DomainName) => {
req.headers["host"] = [{ key: "host", value: s3DomainName }];
};
const isDataRequest = (uri) => uri.startsWith("/_next/data");
const normaliseUri = (uri) => (uri === "/" ? "/index" : uri);
const normaliseS3OriginDomain = (s3Origin) => {
if (s3Origin.region === "us-east-1") {
return s3Origin.domainName;
}
if (!s3Origin.domainName.includes(s3Origin.region)) {
const regionalEndpoint = s3Origin.domainName.replace("s3.amazonaws.com", `s3.${s3Origin.region}.amazonaws.com`);
return regionalEndpoint;
}
return s3Origin.domainName;
};
const router = (manifest) => {
const { pages: { ssr, html } } = manifest;
const allDynamicRoutes = Object.assign(Object.assign({}, ssr.dynamic), html.dynamic);
return (uri) => {
let normalisedUri = uri;
if (isDataRequest(uri)) {
normalisedUri = uri
.replace(`/_next/data/${manifest.buildId}`, "")
.replace(".json", "");
}
if (ssr.nonDynamic[normalisedUri]) {
return ssr.nonDynamic[normalisedUri];
}
console.log(uri);
for (const route in allDynamicRoutes) {
const { file, regex } = allDynamicRoutes[route];
const re = new RegExp(regex, "i");
const pathMatchesRoute = re.test(normalisedUri);
if (pathMatchesRoute) {
return file;
}
}
if (html.nonDynamic["/404"] !== undefined) {
return "pages/404.html";
}
return "pages/_error.js";
};
};
exports.handler = (event) => __awaiter(void 0, void 0, void 0, function* () {
const request = event.Records[0].cf.request;
const uri = normaliseUri(request.uri);
const manifest = manifest_json_1.default;
const prerenderManifest = prerender_manifest_json_1.default;
const { pages, publicFiles } = manifest;
const isStaticPage = pages.html.nonDynamic[uri];
const isPublicFile = publicFiles[uri];
const isPrerenderedPage = prerenderManifest.routes[request.uri];
const origin = request.origin;
const s3Origin = origin.s3;
const isHTMLPage = isStaticPage || isPrerenderedPage;
const normalisedS3DomainName = normaliseS3OriginDomain(s3Origin);
s3Origin.domainName = normalisedS3DomainName;
if (isHTMLPage || isPublicFile) {
s3Origin.path = isHTMLPage ? "/static-pages" : "/public";
addS3HostHeader(request, normalisedS3DomainName);
if (isHTMLPage) {
request.uri = `${uri}.html`;
}
return request;
}
const pagePath = router(manifest)(uri);
if (pagePath.endsWith(".html")) {
s3Origin.path = "/static-pages";
request.uri = pagePath.replace("pages", "");
addS3HostHeader(request, normalisedS3DomainName);
return request;
}
const page = require(`./${pagePath}`);
const { req, res, responsePromise } = next_aws_cloudfront_1.default(event.Records[0].cf);
if (isDataRequest(uri)) {
const { renderOpts } = yield page.renderReqToHTML(req, res, "passthrough");
res.setHeader("Content-Type", "application/json");
res.end(JSON.stringify(renderOpts.pageData));
}
else {
page.render(req, res);
}
return responsePromise;
});
Permission:
Allow: logs:CreateLogGroup
Allow: logs:CreateLogStream
Allow: logs:PutLogEvents
What else should I do? Should I create a new stream or is it automatically created? I can see a log group in my cloudwatch named aws/lambda but i'm not sure how to connect them
Really appreciate any help
Cheers

Related

How to get around the mkdir error in node js? I have been trying to figure it out for hours but to no avail

The error thrown in the cmd is as shown below in the link
Error as shown on cmd
Below is the code for connection-manager.js as shown in the error log, specifically at line 47
"use strict";
const fs = require("fs");
const path = require("path");
const AbstractConnectionManager = require("../abstract/connection-manager");
const { logger } = require("../../utils/logger");
const debug = logger.debugContext("connection:sqlite");
const dataTypes = require("../../data-types").sqlite;
const sequelizeErrors = require("../../errors");
const parserStore = require("../parserStore")("sqlite");
const { promisify } = require("util");
class ConnectionManager extends AbstractConnectionManager {
constructor(dialect, sequelize) {
super(dialect, sequelize);
if (this.sequelize.options.host === "localhost") {
delete this.sequelize.options.host;
}
this.connections = {};
this.lib = this._loadDialectModule("sqlite3");
this.refreshTypeParser(dataTypes);
}
async _onProcessExit() {
await Promise.all(Object.getOwnPropertyNames(this.connections).map((connection) => promisify((callback) => this.connections[connection].close(callback))()));
return super._onProcessExit.call(this);
}
_refreshTypeParser(dataType) {
parserStore.refresh(dataType);
}
_clearTypeParser() {
parserStore.clear();
}
async getConnection(options) {
options = options || {};
options.uuid = options.uuid || "default";
if (!!this.sequelize.options.storage !== null && this.sequelize.options.storage !== void 0) {
options.storage = this.sequelize.options.storage;
} else {
options.storage = this.sequelize.options.host || ":memory:";
}
options.inMemory = options.storage === ":memory:" ? 1 : 0;
const dialectOptions = this.sequelize.options.dialectOptions;
const defaultReadWriteMode = this.lib.OPEN_READWRITE | this.lib.OPEN_CREATE;
options.readWriteMode = dialectOptions && dialectOptions.mode || defaultReadWriteMode;
if (this.connections[options.inMemory || options.uuid]) {
return this.connections[options.inMemory || options.uuid];
}
if (!options.inMemory && (options.readWriteMode & this.lib.OPEN_CREATE) !== 0) {
fs.mkdirSync(path.dirname(options.storage), { recursive: true });//line 47
}
const connection = await new Promise((resolve, reject) => {
this.connections[options.inMemory || options.uuid] = new this.lib.Database(options.storage, options.readWriteMode, (err) => {
if (err)
return reject(new sequelizeErrors.ConnectionError(err));
debug(`connection acquired ${options.uuid}`);
resolve(this.connections[options.inMemory || options.uuid]);
});
});
if (this.sequelize.config.password) {
connection.run(`PRAGMA KEY=${this.sequelize.escape(this.sequelize.config.password)}`);
}
if (this.sequelize.options.foreignKeys !== false) {
connection.run("PRAGMA FOREIGN_KEYS=ON");
}
return connection;
}
releaseConnection(connection, force) {
if (connection.filename === ":memory:" && force !== true)
return;
if (connection.uuid) {
connection.close();
debug(`connection released ${connection.uuid}`);
delete this.connections[connection.uuid];
}
}
}
module.exports = ConnectionManager;
module.exports.ConnectionManager = ConnectionManager;
module.exports.default = ConnectionManager;
//# sourceMappingURL=connection-manager.js.map
**The error begins at line 47 ** as shown in the code snippet, please i really do need help with this coz it's been a huge reason for delay in accomplishing the given task.

why nested async/await doesn't work as intended?

I'm learning NodeJs and having some problems using async/ await. I'm using Firebase database to read/write data. Here what i'm doing. (full function in case you need it).
async getImport(reqData: any): Promise<any> {
const username = 'kdat0310';
const db = admin.database();
const userRef = db.ref('/user');
const importRef = db.ref('/import');
const refAuthentication = db.ref('/Authentication');
const keyList = [];
const providerKey = [];
const khoList = [];
let index = 0;
const providerList = [];
const isValid = await refAuthentication.once('value', function (snapshot) {
for (const val of Object.values(snapshot.val())) {
if (
Object(val).username === Object(reqData).username &&
Object(val).token === Object(reqData).token
) {
return true;
}
}
return false;
});
if (isValid) {
await userRef.once('value', function (snapshot) {
for (const value of Object.values(snapshot.val())) {
if (value) {
if (Object(value).username == username) {
for (const val of Object(value).workAt) {
if (val) khoList.push(val.khoId);
}
}
}
}
});
const typeAndColorKey = [];
const typeAndColorValue = [];
const typeAndColorRef = db.ref('/TypeAndColor');
await typeAndColorRef.once('value', function (snapshot) {
let count = 0;
for (const key in snapshot.val()) {
typeAndColorKey.push(key);
}
for (const value of snapshot.val()) {
if (value !== undefined && value != null) {
typeAndColorValue.push({
id: typeAndColorKey[count],
type: value.type,
color: value.color,
});
count = count + 1;
}
}
});
const findTypeAndColor = (id: any) => {
for (const value of typeAndColorValue) {
if (id == value.id) {
return { type: value.type, color: value.color };
}
}
};
const userKey = [];
const userList = [];
await userRef.once('value', function (snapshot) {
let count = 0;
for (const key in snapshot.val()) {
userKey.push(key);
}
for (const value of Object(snapshot.val())) {
if (value != undefined && value != null) {
userList.push({
id: userKey[count],
name: Object(value).name,
});
count++;
}
}
});
const findUserName = (userId: any) => {
const returnValue = '';
for (const value of userList) {
if (userId == Object(value).id) {
return Object(value).name;
}
}
};
const importList = [];
await importRef.once('value', async function (snapshot) {
const importKey = [];
const cloneArr = snapshot.val().map((item: any) => {
return item;
});
for (const key in snapshot.val()) {
importKey.push(key);
}
let countTemp = 0;
for (const value of Object.values(cloneArr)) {
const goodsKeyList = [];
let count = 0;
if (khoList.indexOf(Object(value).warehouseId) !== -1) {
const listGoodsList = [];
if (Object(value).listGoods) {
for (const key in Object(value).listGoods) {
goodsKeyList.push(key);
}
const refListGoods = db.ref(
'/import/' + importKey[countTemp] + '/listGoods',
);
await refListGoods.once('value', function (snapshot) {
let item: any;
for (item of Object.values(snapshot.val())) {
if (item) {
const tempItem = item.filter((n: any) => n);
listGoodsList.push({
typeAndColor: findTypeAndColor(goodsKeyList[count]),
listGoods: tempItem,
number: tempItem.length,
});
}
count++;
}
});
}
console.log('test 1', listGoodsList);
if (listGoodsList !== []) {
importList.push({
listGoods: listGoodsList,
driver: Object(value).driver,
userId: Object(value).importEmployee,
name: findUserName(Object(value).importEmployee),
orderId: Object(value).orderId,
warehouseId: Object(value).warehouseId,
time: Object(value).time,
});
}
}
countTemp++;
}
console.log('test 2', importList);
});
return importList;
}
return 'Invalid';
}
The problem show up when it came to await importRef.once When I tried to handle some data and add the Firebase once function "async" and await inside to push the data I need to the array. Then return importList; return nothing. I figure that the await refListGoods.once cause this problems. As i thought, the await inside had done its duty and I can console.log importList inside very well. But I thought that await importRef.once will finish before return too. when I delete await refListGoods.once, the return is fine but I dont get the data I need. Do I need to refactor all code as I do to findTypeAndColor and findUserName above or there's a better way to solve this problem?
If you want to use await on the Promise returned by once, you should not pass a callback function to it.
So instead of:
const isValid = await refAuthentication.once('value', function (snapshot) {
for (const val of Object.values(snapshot.val())) {
if (
Object(val).username === Object(reqData).username &&
Object(val).token === Object(reqData).token
) {
return true;
}
}
return false;
});
Do:
const snapshot = await refAuthentication.once('value');
let isValid = false;
snapshot.forEach((child) => {
const val = child.val();
if (val.username === Object(reqData).username &&
val.token === Object(reqData).token
) {
isValid = true;
}
})

I need help to get a simple query for MongoDB (SQL equivalent: "select speed from values")

I need help to get a simple query for MongoDB (SQL equivalent: "select speed from values"). But I can't find a solution for that.
Node.js backend for Vue.js
// a Part of Init-function:
await collection.replaceOne({}, {
speed: {
value: 65,
type: 2,
},
eightSpeed: {
value: 0.0043,
type: 2,
},
oSpeed: {
value: 0.31,
type: 2,
},
minusSpeed: {
value: 2.42,
type: 2,
}
}
//...
Now I need the query like this: http://192.168.220.220:3000/settings/getValue/speed to get an object speed.
const express = require("express");
const mongodb = require("mongodb");
const SettingsRouter = new express.Router();
SettingsRouter.get("/getValue/:value", async function (req, res) {
try {
const val = req.params.value; // req.body.text;
const select = {};
select[`${val}.value`] = 1;
console.log("settings.js:", "/getValue/:name", select);
const collection = await loadMongoCollection();
const value = await collection.findOne({},select)//.toArray();
res.status(201).send(value);
} catch (error) {
res.status(500).send("Failed to connect Database");
console.error("settings.js:", "/getValue/:name:", error);
}
});
async function loadMongoCollection() {
const dbUri = process.env.MONGODB_CONNSTRING || config.dbUri;
const MongoDB = process.env.MONGODB_DB || config.db;
try {
const client = await mongodb.MongoClient.connect(dbUri, {
useNewUrlParser: true,
});
const conn = client.db(MongoDB).collection("values");
return conn;
} catch (error) {
console.error("settings.js:", "loadMongoCollection:", error);
}
}
When I try it, I get all (not only the Speed Object) what I expected, or nothing.
What I do wrong?
EDIT 2022.01.06:
I try it to change my database:
data = {
speed: {
value: 65,
type: 2,
},//...
}
//...
await collection.replaceOne({}, {values:data}, { upsert: true });
And then the query:
const select = {[`values.${val}.value`]:"1"};
const where = {}; //{"values":val};
const value = await collection.find(where,select,).toArray();
But it will not work in rest... is there an issue in mongo package?
When I do it in https://cloud.mongodb.com - it works:
But my request returns all values...
Log shows:"'settings.js:', '/getValue/:name', { 'values.speed.value': '1' }"
In the screenshot you show the projection is values.speed.value, but in your endpoint you have:
const select = {};
select[`${val}.value`] = 1;
Which would evaluate to speed.value. To mimic what you have on the MongoDB console this should be:
const select = {};
select[`values.${val}.value`] = 1;
So, I changed my Frondend (vue) to spred all Values. I maked some Helper Functions:
CheckForChangedObj
check two object for changes
updateObj
copy all data from object into another
export function CheckForChangedObj(targetObject, obj) {
if (targetObject === typeof undefined || targetObject == {}) {
return true
}
if (JSON.stringify(targetObject) !== JSON.stringify(obj)) {
return true
}
return false
}
export function updateObj(targetObject, obj) {
let keys = Object.keys(obj)
for (let k in keys) {
try {
let key = keys[k]
if (!targetObject.hasOwnProperty(key)) {
//define target, if not exist
targetObject[key] = {}
}
//Workaround for References
if (obj[key].hasOwnProperty("__v_isRef")) {
if (targetObject[key].hasOwnProperty("__v_isRef")) {
targetObject[key].value = obj[key].value
} else {
targetObject[key] = obj[key].value
}
} else {
//Source i a Norm Value
//check for an Object inside, then go in...
if ("object" === typeof obj[key] && !Array.isArray(obj[key])) {
updateObj(targetObject[key], obj[key]) // recurse
} else {
//not else-if!!! __v_isRef: true
if (targetObject[key].hasOwnProperty("__v_isRef")) {
targetObject[key].value = obj[key]
} else {
targetObject[key] = obj[key]
}
}
}
} catch (error) {
console.log(
"key:",
keys[k],
"Error:",
error
)
}
}
}
Then spreading...
import {updateObj,CheckForChangedObj } from "../tools/tools"
beforeMount() {
this.getAllValuesAPI()
setInterval(() => {
this.checkForChanges()
// ml("TABLE", this.values)
}, 10000)
},
setup() {
let prevValues = {}
let values = {
speed: {
id:1,
type: SettingType.Slider,
value: ref(0)
}
//...
}
function checkForChanges() {
//intervaled function to get changes from API
let changed = CheckForChangedObj(this.values, this.prevValues)
if (changed) {
updateObj(this.prevValues, this.values)
setValuesToAPI()
}
else{
getAllValuesFromAPI()
}
}
async function getAllValuesFromAPI() {
//get ALL Settings-Data from API, and put them in values
const res = await axios.get(`settings/getAll`)
return updateObj(this.values, res.data[0].values) u
}
}
When you have a better solution, please help...

How to mock redis client in nodejs using jest

I have tried to mock the redisClient.js using redis-mock using jest. But I couldn't find the solution for it. please give me a code sample for it. I need to mock it in controller.
redisClient.js
const redis = require('redis');
const asyncRedis = require("async-redis");
//Redis
const connection = redis.createClient(process.env.REDIS_PORT,
{
retry_strategy: function(options) {
if (options.error && options.error.code === "ECONNREFUSED") {
// End reconnecting on a specific error and flush all commands with
// a individual error
return new Error("The server refused the connection");
}
if (options.total_retry_time > 1000 * 60 * 60) {
// End reconnecting after a specific timeout and flush all commands
// with a individual error
return new Error("Retry time exhausted");
}
if (options.attempt > 10) {
// End reconnecting with built in error
return undefined;
}
// reconnect after
return Math.min(options.attempt * 100, 3000);
},
}
);
module.exports = asyncRedis.decorate(connection);
Controller
const logger = require('../../helper/logger');
const response = require("../../config/response");
const constant = require('../../config/constant');
const QuizService = require('../../services/quiz/quizService');
class QuizController {
constructor() {
this.quizService = new QuizService();
}
async getQuiz(req, res) {
const { userId, query: { campaignId } } = req;
try {
const question = await this.quizService.getQuestion(userId, campaignId);
res.send(response.res(true, constant.MSG.Quiz_FETCHED, question));
} catch (error) {
res.status(constant.RESPONSE.INTERNAL_ERROR.CODE)
.send(response.res(false, error.message, null, error.code))
}
}
}
Service
const _ = require('lodash');
const moment = require('moment');
const { Op } = require('sequelize');
const { v4: uuidv4 } = require("uuid");
const shuffle = require('shuffle-array');
const serialize = require("serialize-javascript");
const utill = require("../../helper/util");
const redis = require("../../cache/redisClient");
const constant = require('../../config/constant');
const scoreHelper = require('./../../helper/scoreHelper');
const db = require("../../models");
const Quiz = db.quiz;
const Campaign = db.campaign;
const campaign = require('../campaign/campaignService')
const SubscriberAnswer = require('../subscriberAnswer/subscriberAnswerService')
const SubscriberProgram = require('../subscriberProgram/SubsciberProgramService')
class quizService {
constructor() {
this.subscriberAnswer = new SubscriberAnswer()
this.subscriberProgram = new SubscriberProgram()
this.campaign = new campaign()
}
async getQuestion(userId, campaignId) {
const subscribedProgramData = await this._checkAvailableQuestionLimit(userId, campaignId)
if(!subscribedProgramData){
throw { message: constant.MSG.TRY_AGAIN }
}
if (subscribedProgramData.no_of_questions > 0) {
const question = await Quiz.findQuestion(userId, campaignId);
if (question.length) {
const data = {
subscriber_id: userId,
campaign_id: campaignId,
questions_id: question[0].id
}
const updateData = {
id: subscribedProgramData.id,
no_of_questions: (subscribedProgramData.no_of_questions - 1)
}
await this.subscriberAnswer.create(data);
await this.subscriberProgram.updateQuota(updateData);
const id = uuidv4();
const {answer, ...questionData } = question[0];
const responseData = await this.handleQuestionData(id, userId, campaignId, questionData, answer);
return responseData;
} else {
throw { code:constant.RESPONSE_COEDES.ALL_ANSWERED, message: constant.MSG.ANSWER_ALL }
}
} else {
throw { message: constant.MSG.QUOTA_OVER }
}
}
}
My Unit Testing Code
const QuizService = require("../../src/services/quiz/quizService");
const QuizController = require("../../src/controllers/quiz/quizController");
const quizService = new QuizService();
const quizController = new QuizController();
const httpMocks = require("node-mocks-http");
jest.mock("../../src/helper/logger");
jest.mock("../../src/cache/redisClient.js");
beforeEach(() => {
req = httpMocks.createRequest();
res = httpMocks.createResponse();
next = jest.fn();
jest.resetAllMocks();
quizService.getQuestion = jest.fn();
});
quizService.getQuestion = jest.fn();
const response = {
id: 1,
name: 'Sandun',
msisdn: '94704377575',
otp: '1234',
deleted: 0,
attempts: 0,
img_url: 'https://'
}
// This test shows how the constructor can be mocked, and how to spy on passed parameters.
describe("Test QuizController", () => {
afterEach(() => {
jest.resetAllMocks();
});
//Because getQuestion is prototype method
it("Test - GetQuiz - Success", async () => {
req.query.programId = 1;
req.userId = 1;
jest.spyOn(QuizService.prototype, "getQuestion").mockReturnValue(response);
await quizController.getQuiz(req, res);
expect(res.statusCode).toBe(200);
});
});
ERROR
FAIL test/controllers/quiz.controller.test.js
● Test suite failed to run
TypeError: Cannot read property 'startsWith' of undefined
//Redis
const connection = redis.createClient(process.env.REDIS_PORT,
^
{
retry_strategy: function(options) {
if (options.error && options.error.code === "ECONNREFUSED") {
at normalizeUrl (node_modules/redis-mock/lib/utils/parseRedisUrl.js:4:11)
at Object.<anonymous>.module.exports (node_modules/redis-mock/lib/utils/parseRedisUrl.js:61:34)
at generateUrlOptions (node_modules/redis-mock/lib/client/createClient.js:25:30)
at unifyOptions (node_modules/redis-mock/lib/client/createClient.js:61:10)
at Object.createClient (node_modules/redis-mock/lib/client/createClient.js:64:47)
at Object.<anonymous> (src/cache/redisClient.js:5:26)
at Object.<anonymous> (src/services/quiz/quizService.js:8:15)
at Object.<anonymous> (test/controllers/quiz.controller.test.js:1:21)

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();
})();

Resources