Peerjs keeps loosing connection and user id is lost - webrtc

I have made an application following a tutorial using peerjs. Everything seems to be working fine except when I make a connection for a video call where I am using peerjs. I have made my own peerjs server which I am running on localhost (right now for testing). Here is the code for the peer server:
const express = require('express');
const path = require('path');
const http = require('http');
const cors = require('cors');
const errorhandler = require('errorhandler');
var ExpressPeerServer = require('peer').ExpressPeerServer;
var options = {
debug: true,
key: 'copycat'
};
var app = express();
var server = http.createServer(app);
var port = process.env.PORT || '3001';
app.set('port', port);
app.use(cors());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/peerjs', ExpressPeerServer(server, options));
app.use(errorhandler());
process.on('uncaughtException', function(exc) {
console.error(exc);
});
server.listen(port);
As you can see I am running the app on port 3001. Now following is the script for peerjs connection for a video call:
// PeerJS
// Compatibility shim
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
// PeerJS object
var peer = new Peer(username + roomId, {
host: 'localhost',
path: '/peerjs',
port: 443,
secure: true,
key: 'copycat',
debug: true
});
peer.on('open', function () {
$('#my-id').text(peer.id);
});
// Receiving a call
peer.on('call', function (call) {
// Answer the call automatically (instead of prompting user) for demo purposes
call.answer(window.localStream);
step3(call);
});
peer.on('error', function (err) {
alert(err.message);
// Return to step 2 if error occurs
step2();
});
// Click handlers setup
$(function () {
$('#make-call').click(function () {
// Initiate a call!
var call = peer.call($('#callto-id').val(), window.localStream);
step3(call);
});
$('#end-call').click(function () {
window.existingCall.close();
step2();
});
step1();
});
function step1() {
// Get audio/video stream
navigator.getUserMedia({ audio: true, video: true }, function (stream) {
// Set your video displays
$('#my-video').prop('src', URL.createObjectURL(stream));
window.localStream = stream;
step2();
}, function () { $('#step1-error').show(); });
}
function step2() {
$('#step1, #step3').hide();
$('#step2').show();
}
function step3(call) {
// Hang up on an existing call if present
if (window.existingCall) {
window.existingCall.close();
}
// Wait for stream on the call, then set peer video display
call.on('stream', function (stream) {
$('#second-video').prop('src', URL.createObjectURL(stream));
});
// UI stuff
window.existingCall = call;
$('#second-id').text(call.peer);
call.on('close', step2);
$('#step1, #step2').hide();
$('#step3').show();
}
This is pretty much the example code from peerjs example file on github. What I am confused about is the port value. Inside the options in the above script its port 443. I get the following error in chrome when I try to make a video call:
peer.js:1492 WebSocket connection to 'wss://localhost/peerjs/peerjs?key=peerjs&id=User80925be509c6c606fa21409858f5&token=zz69b3ccyk' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
Socket._startWebSocket # peer.js:1492
Socket.start # peer.js:1481
Peer._initialize # peer.js:1058
Peer # peer.js:962
(anonymous) # 5be509c6c606fa21409858f5:183
peer.js:1741 PeerJS: Socket closed.
peer.js:1741 PeerJS: ERROR Error: Lost connection to server.
peer.js:1555 POST https://localhost/peerjs/peerjs/User80925be509c6c606fa21409858f5/zz69b3ccyk/id?i=0 net::ERR_CONNECTION_REFUSED
Socket._startXhrStream # peer.js:1555
Socket.start # peer.js:1480
Peer._initialize # peer.js:1058
Peer # peer.js:962
(anonymous) # 5be509c6c606fa21409858f5:183
peer.js:1741 PeerJS: ERROR Error: Lost connection to server.
Please advise what am I doing wrong???

If you are using at your local end then use your localport i.e. 3001 else use 443
make object like this
var peer = new Peer(undefined, {
host: 'localhost',
path: '/peerjs',
port: 3001,
secure: true,
key: 'copycat',
debug: true
});

Related

Express JS Websocket Connection to wss failed without error but still able to communicate

I am using an Express JS to initiate websocket connection. Below is the following configuration that I used.
socket.js
const ip_address = `${process.env.MIX_HTTPS_APP_URL}`;
const socket_port = `${process.env.MIX_EXPRESS_PORT}`;
const URL = ip_address + ":" + socket_port;
export const socket = io(URL, { autoConnect: true });
socket.onAny((event, ...args) => {
// console.log(event, args);
});
index.js
const app = express();
// app settings
/** Create HTTP server. */
const privateKey = fs.readFileSync(env.privateKey, "utf8");
const certificate = fs.readFileSync(env.certificate, "utf8");
const options = {
key: privateKey,
cert: certificate,
};
const server = https.createServer(options, app).listen(port);
/** Create socket connection */
const socketio = new Server(server);
global.io = socketio.listen(server, {
cors: {
origin: env.url,
},
});
global.io.on("connection", WebSockets.connection);
/** Listen on provided port, on all network interfaces. */
/** Event listener for HTTP server "listening" event. */
server.on("listening", () => {
console.log(`Listening on port:: ${env.url}:${port}/`);
});
Though I can emit and listen to socket, I am still getting this error message. How should I solve this so that users wont see this error message when they view the console?
With reference to your example, the listening on port should be on http server, & socket.io should just attach to on new conn.
see doc https://socket.io/docs/v4/server-initialization/#with-an-https-server
Hope this helps.

nestjs: ws:// works but wss://localhost:port/ got ‘WebSocket connection to 'wss://localhost:10086/' failed: ‘

i was trying to create wss server in using nestjs,but when i finished all configuration in a new nestjs project and tried to connect to the server via 'wss://localhost:port', i got the error below:
WebSocket connection to 'wss://localhost:10033/' failed:
enter image description here
and the main.ts is like this:
async function bootstrap() {
const {key, cert} = await readKeyAndCert()
const app = await NestFactory.create(AppModule, {
httpsOptions: {
requestCert: false,
rejectUnauthorized: false,
key,cert
}
});
app.enableCors()
app.useWebSocketAdapter(new WsAdapter(app))
app.useGlobalFilters(
new HttpExceptionFilter()
)
await app.listen(HTTP_PORT);
}
what can i do to fix the wss:// connection?

Websocket fails after implementing CloudFlare

I have implemented cloudflare on a live website, the website has a socket server that's setup with socket.io and express, everything were working fine before implementing cloudflare
Currently I'm using port: 2053 which i've allowed access to through Laravel forge
socket.js
var app = require('express')();
const fs = require('fs');
var server = require('https').createServer({
key: fs.readFileSync('/etc/nginx/ssl/mywebsite.com/1234/server.key'),
cert: fs.readFileSync('/etc/nginx/ssl/mywebsite.com/1234/server.crt'),
}, app);
var io = require('socket.io')(server, {
cors: {
origin: function(origin, fn) {
if (origin === "http://mywebsite.test" || origin === "https://mywebsite.com") {
return fn(null, origin);
}
return fn('Error Invalid domain');
},
methods: ['GET', 'POST'],
'reconnect': true
},
});
var Redis = require('ioredis');
var redis = new Redis();
redis.subscribe('asset-channel', () => {
console.log('asset-channel: started');
});
redis.on('message', function(channel, message) {
var message = JSON.parse(message);
io.to(message.data.id).emit(channel + ':' +message.event + ':'+ message.data.id, message.data);
});
io.on("connection", (socket) => {
socket.on("join:", (data) => {
socket.join(data.id);
});
socket.on("leave:", (data) => {
socket.leave(data.id);
});
});
server.listen(2053, () => {
console.log('Server is running!');
});
app.js
if (! window.hasOwnProperty('io')) {
// if (
// window.origin === "http://mywebsite.test" ||
// window.origin === "https://mywebsite.com" ||
// window.origin == "https://mywebsite.test"
// ) {
window.io = io.connect(`${window.origin}:2053`);
window.io.on('connection');
// }
}
As mentioned before everything were working fine before implementing cloudflare and i have tried to read some different documentation like:
https://developers.cloudflare.com/cloudflare-one/policies/zero-trust/cors
https://socket.io/docs/v4/handling-cors/
I found many different problems similar online, and tried several solutions but nothing seem to make the socket connection work
Tried to allow all cors like so:
var io = require('socket.io')(server, {
cors: {
origin: "*",
methods: ['GET', 'POST'],
'reconnect': true
},
});
Didn't work either, tried configure some stuff in nginx which didn't work either
Error
Access to XMLHttpRequest at 'https://mywebsite.com:2053/socket.io/?EIO=4&transport=polling&t=NurmHmi' from origin 'https://mywebsite.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I think i might have to configure something in the cloudflare dashboard, i just dont know what and my googling skills could not take me to the finish line this time around.
Im not too experienced with sockets so it would be awesome if there are some skilled socket expert who have had this issue before who can guide me in the correct direction? :)
I made it run by adding this to the app.js:
window.io = io.connect(`${window.origin}:2053`, { transports: ["websocket"] });
Apparently it will try to use polling instead of websocket.

Open socket on dynamic endpoint

I am using loopback to build a route:
/users/{id}
where users can listen for new information pertaining to their account on their own endpoint.
I know I need the socket.io package but I'm not sure what to do with it. How can I open a socket on this dynamic endpoint in the function:
#get('/users/{id}', {
responses: {
'200': {
description: 'User socket',
content: {'application/json': {schema: {'x-ts-type': User}}},
},
},
})
async updateUser(#param.path.string('id') userId: typeof User.prototype.id)
: Promise<boolean> {
\\ Open socket here
console.log(userId)
return true;
}
if I do this:
const express = require("express");
const app = express();
const server = require("http").createServer(app);
const io = require("socket.io").listen(server);
const port = 3000;
io.on("connection", socket => {
console.log("User has connected!");
});
It doesn't open a socket on the dynamic endpoint that I want it to.
I am using loopback-4 for the backend and react-native for the front-end.

webRTC ReferenceError: webkitRTCPeerConnection is not defined

I am study about learning WebRTC book and create a demo 4 chapter. I am gating an error in console:
ReferenceError: webkitRTCPeerConnection is not defined
and not understand what can I confi the "iceServers":
Here is my javascript code
function hasUserMedia(){
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
return !!navigator.getUserMedia;
}
function hasRTCPeerConnection() {
window.RTCPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection || window.mozRTCPeerConnection;
return !!window.RTCPeerConnection;
}
//This function will create our RTCPeerConnection objects, set up the SDP offer and response, and find the ICE candidates for both peers. page 48
function startPeerConnection(stream) {
var configuration = {
// Uncomment this code to add custom iceServers
"iceServers": [{ "url": "stun:stun.1.google.com:19302" }]
};
yourConnection = new webkitRTCPeerConnection(configuration);
theirConnection = new webkitRTCPeerConnection(configuration);
// Setup stream listening
yourConnection.addStream(stream);
theirConnection.onaddstream = function (e) {
theirVideo.src = window.URL.createObjectURL(e.stream);
};
// Setup ice handling
yourConnection.onicecandidate = function (event) {
if (event.candidate){
theirConnection.addIceCandidate(new RTCIceCandidate(event.candidate));
}
};
theirConnection.onicecandidate = function (event) {
if (event.candidate) {
yourConnection.addIceCandidate(new RTCIceCandidate(event.candidate));
}
};
// Begin the offer
yourConnection.createOffer(function (offer) {
yourConnection.setLocalDescription(offer);
theirConnection.setRemoteDescription(offer);
theirConnection.createAnswer(function (offer) {
theirConnection.setLocalDescription(offer);
yourConnection.setRemoteDescription(offer);
});
});
}
var yourVideo = document.querySelector("#yours"),
theirVideo = document.querySelector("#theirs"),
yourConnection, theirConnection;
if (hasUserMedia()) {
navigator.getUserMedia({ video: true, audio: false }, function (stream) {
yourVideo.src = window.URL.createObjectURL(stream);
if (hasRTCPeerConnection()) {
startPeerConnection(stream);
} else {
alert("Sorry, your browser does not support WebRTC.");
}
}, function (error) {
console.log(error);
}
);
} else {
alert("Sorry, your browser does not support WebRTC.");
}
and it output like this..
Please let me know why my video not working properly? Please help me to do this
learning WebRTC
Change:
yourConnection = new webkitRTCPeerConnection(configuration);
into:
yourConnection = new RTCPeerConnection(configuration);
as webkitRTCPeerConnection is for Chrome browsers, and the code already defines window.RTCPeerConnection in hasRTCPeerConnection so that it works for most browsers (inclusing Firefox that you are using).
[EDIT]
Your logic is not correct in this program. You are creating both connections like this:
yourConnection = new webkitRTCPeerConnection(configuration);
theirConnection = new webkitRTCPeerConnection(configuration);
This is not logical. Your program is one peer of a 2-peers connection. You need to setup your connection only. Also, you need some kind of messaging server to transmit SDP messages between the two peers. This is not the role of the ICE server.
Your ICE configuration is fine. You are using a public Google STUN server to handle the streaming and the public IP discovery necessary for establishing the WebRTC connection.