简体   繁体   English

http-proxy-rules和Websockets

[英]http-proxy-rules and Websockets

I haven't been able to find any documentation/answer to my needs. 我找不到任何文件/答案来满足我的需求。

I'm in something of a pickle. 我有点腌渍。 I'm developing a websocket application which will allow module expansion by creating new services (websocket servers). 我正在开发一个websocket应用程序,它将通过创建新服务(websocket服务器)来扩展模块。 Of course this means more ports to connect to. 当然这意味着要连接的端口越来越多。 The problem is, our corporate policy only has a very few ports open so I need to proxy my requests. 问题是,我们的公司政策只有很少的端口,所以我需要代理我的请求。

I've read many answers saying to use NGINX, but I simply can't. 我已经阅读了许多使用NGINX的答案,但我根本不能。 First off I'm running windows, second our company is very strict on what can and can't be used. 首先,我正在运行Windows,第二,我们公司对可以使用和不可以使用的内容非常严格。 I am able to install any node module, though. 不过,我可以安装任何节点模块。 I've attempted to use the http-proxy module along with http-proxy-rules. 我试图使用http-proxy模块和http-proxy-rules。

The problem is, I'm getting 404's on every websocket request. 问题是,我在每个websocket请求上都得到了404。 I'll note that the default proxy (for normal webservice, not sockets) is working 100% fine. 我会注意到默认代理(对于普通的web服务,而不是套接字)工作正常100%。

Here's my current code: 这是我目前的代码:

var http = require('http'),
      httpProxy = require('http-proxy'),
      HttpProxyRules = require('http-proxy-rules');

  // Set up proxy rules instance
  var proxyRules = new HttpProxyRules({
    rules: {
      '.*/ws/admin': 'http://localhost:26266', // Rule for websocket service (admin module)
      '.*/ws/quickquery': 'http://localhost:26265' // Rule for websocket service (quickquery module)
    },
    default: 'http://Surface.levisinger.com:8080' // default target
  });

  // Create reverse proxy instance
  var proxy = httpProxy.createProxy();

  // Create http server that leverages reverse proxy instance
  // and proxy rules to proxy requests to different targets
  http.createServer(function(req, res) {

    // a match method is exposed on the proxy rules instance
    // to test a request to see if it matches against one of the specified rules
    var target = proxyRules.match(req);
    if (target) {     
      //console.log(req); 
      console.log("Returning " + target + " for " + req.headers.host);
      return proxy.web(req, res, {
        target: target,
        ws: true
      });      
    }

    res.writeHead(500, { 'Content-Type': 'text/plain' });
    res.end('The request url and path did not match any of the listed rules!');
  }).listen(5050);

My client code connecting to the websocket looks like this: 我连接到websocket的客户端代码如下所示:

var servPath = (cliSettings["AppPaths"]["Admin"] == null) ? 'http://' + window.location.hostname + ':5050' : cliSettings["AppPaths"]["Admin"],
    AdminIO = new io(servPath, {
        extraHeaders: {
            Service: "Admin"
        },
        path: '/ws/admin'})

... ...

And the websocket server is called like this: websocket服务器的调用方式如下:

io = require('socket.io').listen(26266,{ path: '/ws/admin'}) // can use up to 26484

I really hope someone here will have an idea. 我真的希望这里有人会有个主意。 Thanks! 谢谢!

Figured out how to do this. 弄清楚如何做到这一点。 There are a few things to this... 1. You have to use custom websocket paths if you want to proxy them. 这有几件事情...... 1.如果你想代理它们,你必须使用自定义websocket路径。 2. You must give the entire path to the websocket when proxying them. 2.在代理它们时,你必须给出websocket的整个路径。 3. You'll need to specify an event to handle websocket (ws) traffic. 3.您需要指定一个事件来处理websocket(ws)流量。

Here's an example for you all. 这是大家的一个例子。

+++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++

Proxy Server: 代理服务器:

var   ini = require('node-ini'),
      conf = ini.parseSync('../settings/config.ini'),
      http = require('http'),
      httpProxy = require('http-proxy'),
      HttpProxyRules = require('http-proxy-rules');

  // Set up proxy rules instance
  var proxyRules = new HttpProxyRules({
    rules: {
      '.*/ws/remote': 'http://' + conf["Server"]["binding"] + ':26267/ws/remote',
      '.*/ws/admin': 'http://' + conf["Server"]["binding"] + ':26266/ws/admin', // Rule for websocket service (admin module)
      '.*/ws/quickquery': 'http://' + conf["Server"]["binding"] + ':26265/ws/quickquery' // Rule for websocket service (quickquery module)      
    },
    default: 'http://' + conf["Server"]["binding"] + ':8080' // default target
  });

  // Create reverse proxy instance
  var proxy = httpProxy.createProxy();

  // Create http server that leverages reverse proxy instance
  // and proxy rules to proxy requests to different targets
  var proxyServer = http.createServer(function(req, res) {

    // a match method is exposed on the proxy rules instance
    // to test a request to see if it matches against one of the specified rules
    var target = proxyRules.match(req);
    if (target) {     
      //console.log(req.url); 
      //console.log("Returning " + target + " for " + req.url);
      return proxy.web(req, res, {
        target: target,
        ws: true
      });      
    }

    res.writeHead(500, { 'Content-Type': 'text/plain' });
    res.end('The request url and path did not match any of the listed rules!');
  }).listen(conf["Server"]["port"]);

//
// Listen to the `upgrade` event and proxy the
// WebSocket requests as well.
//
proxyServer.on('upgrade', function (req, socket, head) {
    var target = proxyRules.match(req);
    if (target) {
        return proxy.ws(req, socket, head, { target: target });      
    }
});
process.on('SIGINT', function() {
   db.stop(function(err) {
     process.exit(err ? 1 : 0);
   });
});

Websocket Server socket listener: Websocket Server套接字监听器:

io = require('socket.io').listen(26266,{ path: '/ws/admin'});

Connect to websocket from client page: 从客户端页面连接到websocket:

AdminIO = new io({path: '/ws/admin'});

+++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++

The example above will proxy my "admin" connection, which is running on port 26266, through port 80. (I'd of course recommend using 443/SSL in every situation, but that's a bit more complex). 上面的示例将通过端口80代理我的“admin”连接,该连接在端口26266上运行。(我当然建议在每种情况下使用443 / SSL,但这有点复杂)。

Hope this helps someone! 希望这有助于某人!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM