peerjs-server icon indicating copy to clipboard operation
peerjs-server copied to clipboard

websocket wss fails when running peerjs attached to express in ssl mode

Open spine001 opened this issue 4 years ago • 0 comments

I'm having an issue, everything works, but I get a socket issue when running peerjs server in secure mode.

I get this error message:

websocket.js:88 WebSocket connection to 'wss://localhost/socket.io/?EIO=4&transport=websocket&sid=GIzVOZeoSyroFUPCAAAA' failed:

only when I run in ssl mode with peerjs attached to express server:

Here is my code:

Server side:

// Dependencies
const express = require('express')
const app = express()
const httpPort = process.env.PORT || 80
const httpsPort = 443
const { ExpressPeerServer } = require('peer')
const path = require('path')
const http = require('http')
const https = require('https')
const fs = require('fs')
const certs = `C:/Users/spine/Documents/Personal Files/ArduinoData/packages/esp8266/hardware/esp8266/2.7.4/libraries/ESP8266WiFi/examples/BearSSL_Server/`


// Certificate & credentials
const privateKey = fs.readFileSync(path.join(certs, 'key.pem'))
const certificate = fs.readFileSync(path.join(certs, 'cert.pem'))
const credentials = {
        key: privateKey,
        cert: certificate
}

const mainServer = http.createServer(app).listen(httpPort, () => { console.log('Main Server listening to port ' + httpPort) })
const httpsServer = https.createServer(credentials, app).listen(httpsPort, () => { console.log('Peer Server listening to port ' + httpsPort) })

const peerServer = ExpressPeerServer(httpsServer, {
        debug: true,
        path: '',
        ssl: {
          key: privateKey,
          cert: certificate,
      },
})

app.use('/peerjs', peerServer) //inside peerServer middleware there is also an app.use('options.path', xyz)
// app.use(peerServer)

const io = require('socket.io')(httpsServer,{
// const io = require('socket.io')(mainServer, {
  cors: {
      origin: "*",
  },
});
const { v4: uuidV4 } = require('uuid')

app.set('view engine', 'ejs')
app.use(express.static('public'))

app.get('/', (req, res) => {
  res.redirect(`/${uuidV4()}`)
})

app.get('/:room', (req, res) => {
  res.render('room', { roomId: req.params.room })
  //console.log('Room Created / Joined')
})

io.on('connection', (socket) => {
    //console.log('IO Connectedd')
    socket.on('join-room', (roomId, userId) => {
        console.log(roomId, userId)
        socket.join(roomId)
        socket.to(roomId).emit('user-connected', userId)

        socket.on('disconnect', () => {
            socket.to(roomId).emit('user-disconnected', userId)
        })
    })
})

CLIENT SIDE:

const socket = io('/')
const videoGrid = document.getElementById('video-grid')
let Peer = window.Peer;
const peer = new Peer({
    host: '/',
    path: '/peerjs',
    debug: 3,
    port: 443,
    secure: true,
});

console.log('***Created peer instance, userId: ' + peer.id)

// Function to obtain stream and then await until after it is obtained to go into video chat call and answer code. Critical to start the event listener ahead of everything to ensure not to miss an incoming call.

const ownVideo = document.createElement('video') // Own Video
ownVideo.muted = true
const peers = {}
// On Receiving Other Persons Call
peer.on("call", async (call) => {
    try {
        let stream = null;
        stream = await navigator.mediaDevices.getUserMedia({
            video: true,
            audio: true
        });
        call.answer(stream) // Send Video Stream On Answer
        const video = document.createElement('video');
        // Send Back Video Stream On Stream
        call.on('stream', userVideoStream => {
            addVideoStream(video, userVideoStream);
        });
    }
    catch (err) {
        /* handle the error */
        console.log('*** ERROR returning the stream: ' + err);
    }
});

(async () => {
    try {
        let stream = null;
        stream = await navigator.mediaDevices.getUserMedia(
            {
                audio: true,
                video: true,
            });
        if (stream != undefined) {
            addVideoStream(ownVideo, stream);
            console.log('added own Video stream');
        } else {
            console.log('You can only access your audio/video media streams over https');
            alert('Sorry retry using https, for security reasons Google Media blocks access to your video stream over unsecure http connections');
        }
    } catch (err) {
        /* handle the error */
        console.log('*** ERROR returning the stream: ' + err);
        alert('Sorry retry using https, for security reasons Google Media blocks access to your video stream over unsecure http connections');
    }
})();


socket.on('user-connected', userId => { // Allow Self To Be Connected To Others
    console.log('User Connected: ' + userId)
    navigator.mediaDevices.getUserMedia({
        video: true,
        audio: true
    }).then(stream => {
        connectToNewUser(userId, stream)
    })
})

socket.on('user-disconnected', userId => {
    if (peers[userId]) peers[userId].close()
})

peer.on('open', id => {
    socket.emit('join-room', ROOM_ID, id)
})

function connectToNewUser(userId, stream) {
    const call = peer.call(userId, stream) // We Connect To Other User
    const video = document.createElement('video')
    call.on('stream', userVideoStream => { // Other User Connects To Us
        addVideoStream(video, userVideoStream)
    })
    call.on('close', () => { // Other User Disconnects
        video.remove()
    })

    peers[userId] = call
}

function addVideoStream(video, stream) {
    video.srcObject = stream
    video.addEventListener('loadedmetadata', () => {
        video.play()
    })
    videoGrid.append(video)
}

Call chain:

  doOpen @ websocket.js:88
  open @ transport.js:44
  probe @ socket.js:332
  onOpen @ socket.js:358
  onHandshake @ socket.js:422
  onPacket @ socket.js:383
  ./node_modules/component-emitter/index.js.Emitter.emit @ index.js:145
  onPacket @ transport.js:105
  callback @ polling.js:98
  onData @ polling.js:102
  ./node_modules/component-emitter/index.js.Emitter.emit @ index.js:145
  onData @ polling-xhr.js:231
  onLoad @ polling-xhr.js:282
  xhr.onreadystatechange @ polling-xhr.js:186

Console messages (debug level 3) to follow execution of the code of the originator client with only one destination client that has connected to the same room: INS: content-ads.js loaded: https://localhost/46366d70-ed75-448e-912a-6f880f691a8c content-tss.js:1 TSS: content-tss.js loaded: https://localhost/46366d70-ed75-448e-912a-6f880f691a8c content-tss.js:1 TSS: Excluding content tss (trigger: send-mesage) script.js:12 ***Created peer instance, userId: null websocket.js:88 WebSocket connection to 'wss://localhost/socket.io/?EIO=4&transport=websocket&sid=GIzVOZeoSyroFUPCAAAA' failed: doOpen @ websocket.js:88 open @ transport.js:44 probe @ socket.js:332 onOpen @ socket.js:358 onHandshake @ socket.js:422 onPacket @ socket.js:383 ./node_modules/component-emitter/index.js.Emitter.emit @ index.js:145 onPacket @ transport.js:105 callback @ polling.js:98 onData @ polling.js:102 ./node_modules/component-emitter/index.js.Emitter.emit @ index.js:145 onData @ polling-xhr.js:231 onLoad @ polling-xhr.js:282 xhr.onreadystatechange @ polling-xhr.js:186 peerjs.min.js:48 PeerJS: Socket open peerjs.min.js:48 PeerJS: Server message received: {type: "OPEN"} c939d0e917.js:2 Fetch finished loading: GET "https://ka-f.fontawesome.com/releases/v5.15.3/css/free.min.css?token=c939d0e917". (anonymous) @ c939d0e917.js:2 P @ c939d0e917.js:2 (anonymous) @ c939d0e917.js:2 (anonymous) @ c939d0e917.js:2 F @ c939d0e917.js:2 (anonymous) @ c939d0e917.js:2 (anonymous) @ c939d0e917.js:2 (anonymous) @ c939d0e917.js:2 (anonymous) @ c939d0e917.js:2 26XHR finished loading: GET "<URL>". c939d0e917.js:2 Fetch finished loading: GET "https://ka-f.fontawesome.com/releases/v5.15.3/css/free-v4-shims.min.css?token=c939d0e917". (anonymous) @ c939d0e917.js:2 P @ c939d0e917.js:2 (anonymous) @ c939d0e917.js:2 (anonymous) @ c939d0e917.js:2 F @ c939d0e917.js:2 (anonymous) @ c939d0e917.js:2 (anonymous) @ c939d0e917.js:2 (anonymous) @ c939d0e917.js:2 (anonymous) @ c939d0e917.js:2 c939d0e917.js:2 Fetch finished loading: GET "https://ka-f.fontawesome.com/releases/v5.15.3/css/free-v4-font-face.min.css?token=c939d0e917". (anonymous) @ c939d0e917.js:2 P @ c939d0e917.js:2 (anonymous) @ c939d0e917.js:2 (anonymous) @ c939d0e917.js:2 F @ c939d0e917.js:2 (anonymous) @ c939d0e917.js:2 (anonymous) @ c939d0e917.js:2 (anonymous) @ c939d0e917.js:2 (anonymous) @ c939d0e917.js:2 peerjs.min.js:64 Fetch finished loading: GET "https://localhost/peerjs/peerjs/id?ts=16268920123780.1915982130423135". (anonymous) @ peerjs.min.js:64 (anonymous) @ peerjs.min.js:64 (anonymous) @ peerjs.min.js:64 (anonymous) @ peerjs.min.js:64 t @ peerjs.min.js:64 r.retrieveId @ peerjs.min.js:64 i @ peerjs.min.js:66 (anonymous) @ script.js:4 25XHR finished loading: POST "<URL>". script.js:50 added own Video stream DevTools failed to load source map: Could not load content for https://unpkg.com/peerjs.min.js.map: HTTP error: status code 404, net::ERR_HTTP_RESPONSE_CODE_FAILURE script.js:64 User Connected: a38b8a6b-a20b-474d-a7dc-21ec89cc9be2 peerjs.min.js:48 PeerJS: Creating RTCPeerConnection. peerjs.min.js:48 PeerJS: Listening for ICE candidates. peerjs.min.js:48 PeerJS: Listening for data channel peerjs.min.js:48 PeerJS: Listening for remote stream peerjs.min.js:48 PeerJS: add tracks from stream A5mZK2ggRpvdrPkwIcWebh6U9N85KUbgXEqa to peer connection peerjs.min.js:48 PeerJS: add connection media:mc_xlvjewkfis to peerId:a38b8a6b-a20b-474d-a7dc-21ec89cc9be2 peerjs.min.js:48 PeerJS: Created offer. peerjs.min.js:48 PeerJS: Set localDescription: RTCSessionDescription {type: "offer", sdp: "v=0\r\no=- 3516836791649381629 2 IN IP4 127.0.0.1\r\ns…9910 label:44f23107-2fe0-41b5-bd32-782a71e686a1\r\n"} for:a38b8a6b-a20b-474d-a7dc-21ec89cc9be2 peerjs.min.js:48 PeerJS: Received ICE candidates for a38b8a6b-a20b-474d-a7dc-21ec89cc9be2: RTCIceCandidate {candidate: "candidate:2399835051 1 udp 2122260223 192.168.2.17…eration 0 ufrag 5GQF network-id 1 network-cost 10", sdpMid: "0", sdpMLineIndex: 0, foundation: "2399835051", component: "rtp", …} peerjs.min.js:48 PeerJS: Received ICE candidates for a38b8a6b-a20b-474d-a7dc-21ec89cc9be2: RTCIceCandidate {candidate: "candidate:2399835051 1 udp 2122260223 192.168.2.17…eration 0 ufrag 5GQF network-id 1 network-cost 10", sdpMid: "1", sdpMLineIndex: 1, foundation: "2399835051", component: "rtp", …} peerjs.min.js:48 PeerJS: Received ICE candidates for a38b8a6b-a20b-474d-a7dc-21ec89cc9be2: RTCIceCandidate {candidate: "candidate:239244575 1 udp 1686052607 24.160.69.63 …eration 0 ufrag 5GQF network-id 1 network-cost 10", sdpMid: "0", sdpMLineIndex: 0, foundation: "239244575", component: "rtp", …} peerjs.min.js:48 PeerJS: Received ICE candidates for a38b8a6b-a20b-474d-a7dc-21ec89cc9be2: RTCIceCandidate {candidate: "candidate:239244575 1 udp 1686052607 24.160.69.63 …eration 0 ufrag 5GQF network-id 1 network-cost 10", sdpMid: "1", sdpMLineIndex: 1, foundation: "239244575", component: "rtp", …} peerjs.min.js:48 PeerJS: Received ICE candidates for a38b8a6b-a20b-474d-a7dc-21ec89cc9be2: RTCIceCandidate {candidate: "candidate:3247009627 1 tcp 1518280447 192.168.2.17…eration 0 ufrag 5GQF network-id 1 network-cost 10", sdpMid: "0", sdpMLineIndex: 0, foundation: "3247009627", component: "rtp", …} peerjs.min.js:48 PeerJS: Received ICE candidates for a38b8a6b-a20b-474d-a7dc-21ec89cc9be2: RTCIceCandidate {candidate: "candidate:3247009627 1 tcp 1518280447 192.168.2.17…eration 0 ufrag 5GQF network-id 1 network-cost 10", sdpMid: "1", sdpMLineIndex: 1, foundation: "3247009627", component: "rtp", …} peerjs.min.js:48 PeerJS: Server message received: {type: "ANSWER", src: "a38b8a6b-a20b-474d-a7dc-21ec89cc9be2", dst: "ad20bd26-ac87-4cdd-86c5-9ecab3cc7f45", payload: {…}} peerjs.min.js:48 PeerJS: Setting remote description RTCSessionDescription {type: "answer", sdp: "v=0\r\no=- 4215392732423779075 2 IN IP4 127.0.0.1\r\ns…N4FmG\r\na=ssrc:2106059672 cname:IjAka21gR1oN4FmG\r\n"} peerjs.min.js:48 PeerJS: Server message received: {type: "CANDIDATE", src: "a38b8a6b-a20b-474d-a7dc-21ec89cc9be2", dst: "ad20bd26-ac87-4cdd-86c5-9ecab3cc7f45", payload: {…}} peerjs.min.js:48 PeerJS: handleCandidate: {candidate: "candidate:2399835051 1 udp 2122260223 192.168.2.17…eration 0 ufrag 6Lj0 network-id 1 network-cost 10", sdpMid: "0", sdpMLineIndex: 0} peerjs.min.js:48 PeerJS: Received remote stream peerjs.min.js:48 PeerJS: add stream gDZM9w8onlnSnAYODlQmfsT8eKfvnT9afCNU to media connection mc_xlvjewkfis peerjs.min.js:48 PeerJS: Receiving stream MediaStream {id: "gDZM9w8onlnSnAYODlQmfsT8eKfvnT9afCNU", active: true, onaddtrack: null, onremovetrack: null, onactive: null, …} peerjs.min.js:48 PeerJS: Received remote stream peerjs.min.js:48 PeerJS: add stream gDZM9w8onlnSnAYODlQmfsT8eKfvnT9afCNU to media connection mc_xlvjewkfis peerjs.min.js:48 PeerJS: Receiving stream MediaStream {id: "gDZM9w8onlnSnAYODlQmfsT8eKfvnT9afCNU", active: true, onaddtrack: null, onremovetrack: null, onactive: null, …} peerjs.min.js:48 PeerJS: Set remoteDescription:ANSWER for:a38b8a6b-a20b-474d-a7dc-21ec89cc9be2 peerjs.min.js:48 PeerJS: Added ICE candidate for:a38b8a6b-a20b-474d-a7dc-21ec89cc9be2

Using Chrome debug with a break point at websocket.js:88 these are the values of the variables: image

spine001 avatar Jul 21 '21 19:07 spine001