通过代理服务器运行NodeBB时出现Websocket错误

时间:2019-05-07 18:00:16

标签: node.js websocket reverse-proxy nodebb

我正在尝试通过node.js反向代理(https://docs.nodebb.org/configuring/proxies/node/)来运行NodeBB

我已经按照每个教程,提示/技巧进行操作,但仍无法解决与NodeBB服务器的websocket连接问题,导致会话问题,无法登录等。

我的设置如下:

应用1-http://www.mywebsite.co.uk/

  • Node.js和Express
  • 针对API和前端网站的路由
  • 没什么不寻常的
  • 帖子底部的完整代码段

我正在使用'http-proxy'npm模块来代理将http://mywebsite.co.uk/forum加载到http://www.myforum.co.uk/forum的任何人

这部分正在工作,资产已按预期加载。但是,NodeBB的一部分使用websockets轮询论坛以达到功能目的,即用户会话。这部分代理不正确,或者至少NodeBB响应不正确,因此给了我很多错误:

  

“您正在从未知来源访问论坛。这很可能会   导致websocket无法连接。要解决此问题,请设置"url"   config.json中的值添加到您访问网站的URL。对于   有关更多信息,请参见以下常见问题解答主题:   https://community.nodebb.org/topic/13388

也:

  

”“看来您与NodeBB的连接已丢失,请等待我们   尝试重新连接。”

并且,在网络面板中,许多“待定”请求最终失败,并由于NodeBB的空响应而失败。

http://mywebsite.co.uk/forum/socket.io/?EIO=3&transport=polling&t=MgJQSMk


应用2-http://www.myforum.co.uk/forum

该应用程序是运行的基本NodeBB安装,带有一个插件-(https://github.com/julianlam/nodebb-plugin-session-sharing

配置JSON文件如下所示(注意,按照代理时的说明,该URL是我的前端应用程序的URL。

{
    "url": "http://www.mywebsite.co.uk/forum",
    "secret": "secret",
    "database": "postgres",
    "port": "4567",
    "postgres": {
        "host": "HOST",
        "port": "PORT",
        "password": "PASSWORD",
        "database": "DATABASE"
    }
}


应用1的代码:

// app
const express = require("express");
const app = express();

app.use(require('cookie-parser')());
app.use(require('body-parser').urlencoded({ extended: true }));
app.use(require('express-session')({ secret: 'secret', resave: true, saveUninitialized: true }));

//
app.use((req, res, next) => {
  res.setHeader("Access-Control-Allow-Origin", "*");
  res.setHeader(
    "Access-Control-Allow-Methods",
    "OPTIONS, GET, POST, PUT, PATCH, DELETE"
  );
  res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
  next();
});

// serve the content
app.use(express.static("dist"));

// Frontend
app.set('view engine', 'pug');

// serve out the api
// app.use ...

// Server set up
const httpProxy = require('http-proxy');
const HttpProxyRules = require('http-proxy-rules');

// Forum urls
let rules = {
  rules: {
    '/forum': 'http://www.myforum.co.uk/forum',
    '/forum/*': 'http://www.myforum.co.uk/forum',
  },
};

const proxyRules = new HttpProxyRules(rules);
const proxy = httpProxy.createProxy();

app.use(function (req, res, next) {
  try {
    if (req.url.includes("socket.io") === true) {
      // console.log("SOCKET.IO", req.url)
      return proxy.web(req, res, {
        target: 'wss://www.myforum.co.uk',
        ws: true,
        changeOrigin: true
      }, function (e) {
        // console.log('PROXY ERR', e)
        // next();
      });

    } else {
      var target = proxyRules.match(req);
      if (target) {
        // console.log("TARGET", target, req.url)
        return proxy.web(req, res, {
          target: target,
          changeOrigin: true
        }, function (e) {
          // console.log('PROXY ERR', e)
        });
      } else {
        next();
      }
    }
  } catch (e) {
    // res.sendStatus(500);
    res.json({ error: e });
  }
});

// Frontend routes
// app.use ...

// HTTP
const http = require('http');

// Create server
mainserver = http.createServer(app);

const PORT = process.env.PORT || 3000;
mainserver.listen(PORT);
mainserver.on('listening', onListening);
mainserver.on('error', function (error, req, res) {
  let json;
  console.log('proxy error', error);
  if (!res.headersSent) {
    res.writeHead(500, { 'content-type': 'application/json' });
  }

  json = { error: 'proxy_error', reason: error.message };
  res.end(JSON.stringify(json));
});

function onListening() {
  console.log(`Listening on :${PORT}`);
}

1 个答案:

答案 0 :(得分:0)

要解决此问题,我更改了所使用的代理模块。它使用更少的代码来实现和与websockets一起工作。我认为NodeBB Node.js代理文档已过时,因此我将使用发现的新方法进行更新。

工作代码如下:

/**
 * Proxy forum
 */
const proxy = require('http-proxy-middleware');

// Forum Proxy
app.use(
  '/forum',
  proxy({
    target: 'http://www.myforum.co.uk/forum',
    changeOrigin: true,
    ws: true,
  })
);

这里的另一个可能的GOTCHA是,此Prixy设置需要声明为 Above “ body-parser”模块(如果正在使用)。错误的顺序将阻止发布请求的请求。