Ошибка веб-сокета при работе NodeBB через прокси-сервер - PullRequest
0 голосов
/ 07 мая 2019

Я пытаюсь запустить NodeBB через обратный прокси-сервер node.js (https://docs.nodebb.org/configuring/proxies/node/)

Я следовал всем урокам, подсказкам и подсказкам, но могу по-прежнему испытывать проблемы с подключениями через веб-сокетна мой сервер NodeBB, вызывая проблемы с сеансом, не могу войти в систему и т. д.

Моя настройка следующая:

Приложение 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, которая использует веб-сокеты для опроса форума на предмет функциональности, пользовательских сессий.Эта часть неправильно проксирует или, по крайней мере, ответ NodeBB неверен и поэтому выдает мне много ошибок:

"Вы заходите на форум неизвестного происхождения.может привести к невозможности подключения веб-сокетов.Чтобы исправить это, установите значение "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 голосов
/ 11 июня 2019

Для решения этой проблемы я изменил используемый мной прокси-модуль. Он использует меньше кода для реализации и работает с веб-сокетами. Я думаю, что документация прокси-сервера 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' (если он используется). Неправильный порядок помешает отправке почтовых запросов.

...