【问题标题】:http-proxy-rules and Websocketshttp-proxy-rules 和 Websockets
【发布时间】:2016-07-29 19:54:17
【问题描述】:

我找不到任何文档/答案来满足我的需求。

我有点像泡菜。我正在开发一个 websocket 应用程序,它将允许通过创建新服务(websocket 服务器)来扩展模块。当然,这意味着要连接更多的端口。问题是,我们的公司政策只开放了很少的端口,所以我需要代理我的请求。

我已经阅读了很多关于使用 NGINX 的答案,但我根本做不到。首先我正在运行Windows,其次我们公司对可以使用和不能使用的内容非常严格。不过,我可以安装任何节点模块。我尝试将 http-proxy 模块与 http-proxy-rules 一起使用。

问题是,我在每个 websocket 请求上都会收到 404。我会注意到默认代理(对于普通的 web 服务,而不是套接字)可以 100% 正常工作。

这是我当前的代码:

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);

我连接到 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'})

...

websocket 服务器是这样调用的:

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

我真的希望这里有人能有一个想法。谢谢!

【问题讨论】:

    标签: node.js windows socket.io reverse-proxy http-proxy


    【解决方案1】:

    想出了如何做到这一点。这有几件事... 1. 如果你想代理它们,你必须使用自定义的 websocket 路径。 2. 代理它们时,您必须提供到 websocket 的完整路径。 3. 您需要指定一个事件来处理 websocket (ws) 流量。

    这是给大家的一个例子。

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

    代理服务器:

    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 服务器套接字监听器:

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

    从客户端页面连接到 websocket:

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

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

    上面的示例将通过端口 80 代理我在端口 26266 上运行的“管理员”连接。(我当然建议在每种情况下都使用 443/SSL,但这有点复杂)。

    希望这对某人有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-05
      • 2018-11-17
      • 2013-09-14
      • 1970-01-01
      相关资源
      最近更新 更多