peers / peerjs-server

Server for PeerJS
https://peerjs.com
MIT License
4.34k stars 1.08k forks source link

Error during WebSocket handshake: Unexpected response code: 200 #168

Closed baggachipz closed 4 years ago

baggachipz commented 4 years ago

I saw similar errors for code 400 and 404, but this one seems strange. After all, I would think a 200 code would mean "everything's ok" right?

"peer": "^0.5.1", "peerjs": "^1.2.0"

On server side:

import { ExpressPeerServer } from 'peer'

const PeerController = {}

PeerController.initialize = function (app) {
  const peerServer = ExpressPeerServer(app, { debug: true, path: '/peerjs' })

  peerServer.on('connection', (client, foo) => {
    console.log(client, foo)
  })

  return peerServer
}

export default PeerController
const app = express()
app.use('/peer', PeerController.initialize(app))

And on the client side (a Vue application):

import Peer from 'peerjs'
export default {
  name: 'Meet',
  data () {
    return {
      peer: null
    }
  },
  mounted () {
    this.peer = new Peer('12345', {
      host: '/',
      port: '3000',
      path: '/peer/',
      debug: 3
    })
    this.peer.on('error', (err) => {
      console.debug(err)
    })
    this.peer.on('open', function (id) {
      console.log(id)
    })
  }
}

vendor.3921cbfb.js:18 WebSocket connection to 'ws://localhost:3000/peer/peerjs?key=peerjs&id=12345&token=697lo3pxz52' failed: Error during WebSocket handshake: Unexpected response code: 200

I noticed that it was 404ing initially until I added the path: '/peerjs' in the ExpressPeerServer constructor, because it seems that no matter what the client library tries to hit that endpoint. Not a huge worry, but after I solved the 404 issue I now get an "error" with a 200 code. Any advice? Thank you very much....

afrokick commented 4 years ago

On the client, the path should be /peer/peerjs

baggachipz commented 4 years ago

If I do that, then it 404's because the request is going to /peer/peerjs/peerjs. Example:

this.peer = new Peer('12345', {
        host: '/',
        port: '3000',
        path: '/peer/peerjs',
        debug: 3
      })

peerjs.min.js?a0bc:52 WebSocket connection to 'ws://localhost:3000/peer/peerjs/peerjs?key=peerjs&id=12345&token=siurrra4bn8' failed: Error during WebSocket handshake: Unexpected response code: 404

So it looks like the client library already appends on '/peerjs' automatically? That's why I changed it in my first example, and got the 200 instead.

afrokick commented 4 years ago

Could you please try to run server as standalone app and connect to it? https://github.com/peers/peerjs-server#run-server

jason-yang31415 commented 4 years ago

@afrokick I was having the same issue (peerjs 1.2.0 and peer server 0.5.1) with the following configs:

// server
var options = {
    debug: true,
    path: "/peer"
}
app.use('/', ExpressPeerServer(server, options));

and

// client
let peer = new Peer(null, {
    debug: 2,
    host: "localhost",
    port: 9000,
    path: "/peer",
});

Looking at networking requests on the client, the GET request to localhost:9000/peer/peerjs/id succeeds but the websocket connection to localhost:9000/peer/peerjs does not work.

I then rolled back the peer server to v0.5.0 and retried, and the client was able to connect to the server. Hope this helps!

baggachipz commented 4 years ago

Could you please try to run server as standalone app and connect to it? https://github.com/peers/peerjs-server#run-server

If I run the server locally straight-up, it works fine. So it would seem it is the Express integration causing the issue.

afrokick commented 4 years ago

@baggachipz @jason-yang31415 Look, it works. https://glitch.com/~prairie-six-ray

baggachipz commented 4 years ago

The only difference I really see is that I pass app into ExpressPeerServer() instead of the product of app.listen()... could this be it? I use http.createServer(app) instead to create my server.

poison commented 4 years ago

Having the same issue, I'm using NextJS so I've created a custom server.ts where I use ExpressJS and I bind the ExpressPeerServer to the route /peerjs and the websocket connection fails with a 404

baggachipz commented 4 years ago

Here's an example of what I'm talking about: https://glitch.com/~prism-iodized-magpie

afrokick commented 4 years ago

@baggachipz do you use windows on local machine?

afrokick commented 4 years ago

@baggachipz you need to create server first, then pass it into ExpressPeerServer

const express = require('express');
const app = express();
const http = require('http');
const { ExpressPeerServer } = require('peer');

const server = http.createServer(app).listen(process.env.PORT); // 1) create

const options = {
    debug: true,
    path: '/xyz'
};

const peerserver = ExpressPeerServer(server, options); // 2) use the 'server' instead of the 'app'

app.use('/abc', peerserver);

app.use("/", express.static("public"));
afrokick commented 4 years ago

@jason-yang31415 @baggachipz please try to update to 0.5.2 It contains a fix for Windows

baggachipz commented 4 years ago

I do not use Windows locally, MacOS Catalina.

Regarding https://github.com/peers/peerjs-server/issues/168#issuecomment-605788722, I cannot use this method because I use a catch-all path to serve up static assets in my Vue application. The catch-all needs to be the last route defined for the express app. So if I create the server (with that catch-all) and then create the Peer server at, say, /peer, the application looks for static assets at that URL and 404's before ever reaching the Peer route. Does that make sense? That is why I try to pass app instead of server into the ExpressPeerServer method.

afrokick commented 4 years ago

@baggachipz do you use static assets like app.use('/', express.static('public')); ? it is enough to serve any app

baggachipz commented 4 years ago

I use:

app.use('/', express.static(path.join(__dirname, 'public/spa')))
app.use('/*', express.static(path.join(__dirname, 'public/spa')))

because I want to allow deep linking in my application to my SPA.

I'm currently trying to use:

app.use(/^(?!\/peer).*$/, express.static(path.join(__dirname, 'public/spa')))

To then defer the lookup for /peer later on but am not having any success yet. Still playing with it.

baggachipz commented 4 years ago

Looks like using the look-ahead regex worked. Might be handy to also allow passing in app instead of server, so that this is easier to handle. But thank you for your assistance!

afrokick commented 4 years ago

@baggachipz Your code looks like this, right?

const app = express()

app.use('/peer', PeerController.initialize(app))
app.use('/', express.static(path.join(__dirname, 'public/spa')))
app.use('/*', express.static(path.join(__dirname, 'public/spa')))

const server = http.createServer(app);

server.listen(port);
afrokick commented 4 years ago

@baggachipz Anyway, join to our telegram chat) https://t.me/joinchat/ENhPuhTvhm8WlIxTjQf7Og

baggachipz commented 4 years ago

@baggachipz Your code looks like this, right?

const app = express()

app.use('/peer', PeerController.initialize(app))
app.use('/', express.static(path.join(__dirname, 'public/spa')))
app.use('/*', express.static(path.join(__dirname, 'public/spa')))

const server = http.createServer(app);

server.listen(port);

That is correct, that's how I was trying to do it initially.