OptimalBits / redbird

A modern reverse proxy for node
BSD 2-Clause "Simplified" License
4.38k stars 279 forks source link

Websocket proxy #12

Open goette opened 9 years ago

goette commented 9 years ago

I'm trying to use redbird to proxy a websocket, but it won't let me do it. Is this a known issue or am I missing something here? Is there an option, or do i need to set the protocoll manually? Thanks for any hint!

// client
var ws = new WebSocket('ws://localhost:9999');

// Server
var redbird = require('redbird');
var proxy = redbird({port: 9999});
proxy.register("localhost:9999", "ws://echo.websocket.org");

// ....
// Start http server on other port

var server = http.createServer(app);
server.listen(process.env.PORT || 61475);
manast commented 9 years ago

I think the problem is that you cannot register the ws: protocol. If you register like this it should work:

proxy.register("localhost:9999", "http://echo.websocket.org");

Let me know if it does work or not and I will help you to debug it.

goette commented 9 years ago

Thanks for your quick reply! I tried you suggestion, but I still receceive the following error on theclient side:

WebSocket connection to 'ws://localhost:9999/' failed: Connection closed before receiving a handshake response

The connection from the proxy to the external ws seems to work, but I can't connect the client without seeing the error:

Heres's the server log, thanks again!

{"name":"redbird","hostname":"Martins-Air","pid":858,"level":30,"msg":"Proxying localhost/ to {  
   "name":"redbird",
   "hostname":"Martins-Air",
   "pid":858,
   "level":30,
   "msg":"Proxying localhost/ to echo.websocket.org/",
   "time":"2015-05-28T18:45:50.154Z",
   "v":0
}{  
   "name":"redbird",
   "hostname":"Martins-Air",
   "pid":858,
   "level":30,
   "headers":{  
      "host":"localhost:9999",
      "connection":"Upgrade",
      "pragma":"no-cache",
      "cache-control":"no-cache",
      "upgrade":"websocket",
      "origin":"http://localhost:61475",
      "sec-websocket-version":"13",
      "dnt":"1",
      "user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.81 Safari/537.36",
      "accept-encoding":"gzip, deflate, sdch",
      "accept-language":"en-US,en;q=0.8,de;q=0.6,fr;q=0.4",
      "cookie":"connect.sid=s%3A-iy9tTKtv3lEVt0HyNgnj9fvwXZ4t86i.AnXfz9IFZBT5W9IZ4WRFSGn8mX%2BCybvDy%2F3NVd4xQB4",
      "sec-websocket-key":"pQt6vH3zkyDZdvzJCmFV6Q==",
      "sec-websocket-extensions":"permessage-deflate; client_max_window_bits"
   },
   "target":{  
      "protocol":"http:",
      "slashes":true,
      "auth":null,
      "host":"echo.websocket.org",
      "port":null,
      "hostname":"echo.websocket.org",
      "hash":null,
      "search":null,
      "query":null,
      "pathname":"/",
      "path":"/",
      "href":"http://echo.websocket.org/",
      "sslRedirect":true,
      "useTargetHostHeader":false
   },
   "msg":"upgrade to websockets",
   "time":"2015-05-28T18:45:50.154Z",
   "v":0
}
manast commented 9 years ago

Ok sorry. I did not pay enough attention to your example so I did not give you a proper answer. Here it comes. redbird is just a reverse proxy, you still need to have a websocket server where the proxy can proxy to. So for example using the ws module in node:

var WebSocketServer = require('ws').Server
  , wss = new WebSocketServer({ port: 8080 });

wss.on('connection', function connection(ws) {
  ws.on('message', function incoming(message) {
    console.log('received: %s', message);
  });

  ws.send('something');
});

Now you can start a redbird proxy and proxy to the given websocket server like this:

var redbird = require('redbird');
var proxy = redbird({port: 80});
proxy.register("optimalbits.com", "http://localhost:8080");
goette commented 9 years ago

Thank you! But how does the connection to the external Websocket play in here? Because the way I understand it, I now would replace the external Websocket [echo.websocket.org] with my internal one on port 8080, which works fine.

But what I basically want to achieve is just hiding the external Websocket's URL from the client, just the way a normal http proxy would do as well. Where do i connect to the [echo.websocket.org] in this set up?

I'm sorry if I have been unclear. It's quite a confusing topic ;)

niemes commented 4 years ago

I'm looking for an answer too on this topic. Any advice ?