kyriesent / node-rtsp-stream

Stream any RTSP stream and output to websocket for consumption by jsmpeg (https://github.com/phoboslab/jsmpeg). HTML5 streaming video! Requires ffmpeg.
MIT License
451 stars 166 forks source link

New request for native WSS support #59

Open mmeyers-solartech opened 4 years ago

mmeyers-solartech commented 4 years ago

I've followed the information provided in I believe #37, to bury the ws server inside of a https server with certificates. This works for me but only under one condition. I have to access the server directly at https://IP:9999 to get the certificates in the browser. Then I can use my actual website to open up that wss:// connection. The server doesn't just listen for and accept an attempt to open a wss:// connection at the node-rtsp stream without me doing that. I can't seem to get around it.

VideoStream.prototype.pipeStreamToSocketServer = function() {
  const server = https.createServer({
    cert: fs.readFileSync('./cert/cert.pem'),
    key: fs.readFileSync('./cert/key.pem'),
  }).listen(9999, '0.0.0.0');
  this.wsServer = new ws.Server({
    server
  })
  this.wsServer.on("connection", (socket, request) => {
    return this.onSocketConnect(socket, request)
  })
  this.wsServer.broadcast = function(data, opts) {
    var results
    results = []
    for (let client of this.clients) {
      if (client.readyState === 1) {
        results.push(client.send(data, opts))
      } else {
        results.push(console.log("Error: Client from remoteAddress " + client.remoteAddress + " not connected."))
      }
    }
    return results
  }
  return this.on('camdata', (data) => {
    return this.wsServer.broadcast(data)
  })
}

This piece of code works perfectly only if the browser is already certified. To do that I have to manually visit the IP the server is running on over https://IP:9999, accept the warnings, then leave. Now my hosted website over https:// can connect to that wss:// socket no problem and play video, but first having to certify with an https: visit is a major problem

mmeyers-solartech commented 4 years ago

This has been identified and solved. The issue is a bit tricky. Depending on where you're hosting the server, you will need to configure DNS so that you can register a REAL SSL/TSL certificate. You'll see in my example the cert.pem and key.pem are just some quick generated self signed certificates. I changed the way my server is hosted (gave it a domain) and generated a real key and cert with the domain name and it works.

Secure browsers like firefox will silently reject wss:// connection attempts in the background so it looks like it's just failing. In my case I had to visit my server directly at https::9999 to accept the warnings which would certify the browser. From there it would work.

That process is completely bypassed if your certificates are legitimate and not self signed. Now my jsmpeg player access wss://mydomain.app:9999 and it starts without question.

The information in #37 is accurate so thank you to everyone in there, this just fills in the blanks it leaves behind. I'll leave the issue open just because native WSS support would be nice, but it's not like the author can generate certs for you.