0

I am running theia editor on port 6080 (say), when I am opening editor at -> localhost:6080 it works perfectly

I am Running a proxy server as below, which is proxying the request from 5000 port to 6080. So when I am accessing the editor over proxy at -> localhost:5000, the editor loads but websocket connection is not happening. And it fails with -> Client disconnected : (meaning proxy.on('close' .. event is getting triggered).

Proxy Server ->node app.js

let http = require("http");
let httpProxy = require("http-proxy");
let proxy = new httpProxy.createProxyServer();

function getPortFromUrl(url) {
    return 6080;
}

var proxyServer = http.createServer(async function (req, res) {
  try {
    if (req.url === "/favicon.ico") {
      res.writeHead(204);
      res.end();
      return;
    }

    // console.log("req.url : ", req.url);

    // NOTE: this logic of getting port I have simplified for DEMO purpose
    let uiPort = getPortFromUrl(req.url);

    if (!uiPort) {
      res.write("problem no port");
      res.end();
      return;
    }

    let targetUrl = "localhost" + ":" + uiPort + req.url.split("/").join("/");
    // console.log("targetUrl : ", targetUrl);
    proxy.web(
      req,
      res,
      {
        target: `http://localhost:${uiPort}`,
        changeOrigin: true,
        ws: true,
        secure: false,
      },
      function (e) {
        console.log(e);
        console.log("an error occured");
      }
    );
  } catch (exception) {
    console.error("Request URL: " + req.url + " " + exception + " exception");
    res.statusCode = 500;
    res.statusMessage = exception;
    res.writeHead(500);
    res.end();
  }
});

//
// Listen to the `upgrade` event and proxy the
// WebSocket requests as well.
//
proxyServer.on("upgrade", function (req, socket, head) {
  let uiPort = getPortFromUrl(req.url);
  console.log("req.url ::", req.url , " targetUrl :: ", `ws://localhost:${uiPort}${req.url.split("/").join("/")}`);
  proxy.ws(req, socket, head, {
    target: `ws://localhost:${uiPort}${req.url.split("/").join("/")}`,
  });
});

proxy.on("error", function (err, req, res) {
  console.error(err);
  //   res.writeHead(500, { "Content-Type": "text/html" });
  //   res.write(`Error`);
  //   res.end();
});

proxy.on('close', function (res, socket, head) {
  // view disconnected websocket connections
  console.error('Client disconnected : ', socket);
});


var server = proxyServer.listen("5000", function () {
  console.info("proxy server started on port 5000");
});

Theia app -> package.json

{
    "private": true,
    "dependencies": {
      "@theia/markers": "next",
      "@theia/terminal": "next",
      "@theia/mini-browser": "next",
      "@theia/plugin": "next",
      "@theia/plugin-ext": "next",
      "@theia/plugin-ext-vscode": "next"
    },
    "devDependencies": {
      "@theia/cli": "next"
    },
    "scripts": {
      "prepare": "yarn run clean && yarn build && yarn run download:plugins",
      "clean": "theia clean",
      "build": "theia build",
      "start": "theia start /Users/pawankumarsingh/Projects/theia --hostname 0.0.0.0 --port 6080 --plugins=local-dir:plugins",
      "download:plugins": "theia download:plugins"
    },
    "theiaPluginsDir": "plugins",
    "theiaPlugins": {
      "redhat.java":"https://open-vsx.org/api/redhat/java/linux-x64/1.14.2022122003/file/redhat.java-1.14.2022122003@linux-x64.vsix"
    },
    "theiaPluginsExcludeIds": [
      "ms-vscode.js-debug-companion",
      "vscode.extension-editing",
      "vscode.git",
      "vscode.git-ui",
      "vscode.github",
      "vscode.github-authentication",
      "vscode.microsoft-authentication"
    ]
  }

For Starting theia editor ->

yarn yarn build yarn start

Any help is much appreciated.

Thanks

I tried looking for this in Theia and http-proxy but didn't get much on it.

[EDIT]

I got it working to some extent by changing the websocket proxy logic like this ->

proxyServer.on("upgrade", function (req, socket, head) {
  let uiPort = getPortFromUrl(req.url);
  proxy.ws(req, socket, head, {
    target: `ws://localhost:${uiPort}`,
  });
});

and editor seems to be loading fine, but I am still getting -> Client disconnected : (meaning proxy.on('close' .. event is getting triggered) on initial load.

[EDIT 2]

The proxy.on('close', ...) event is getting called because the WebSocket connection is closed by the server. This is a normal behavior as the WebSocket connection is closed after the initial handshake is completed.

When the Theia editor is loaded for the first time, it establishes a WebSocket connection with the server to enable real-time communication. After the initial handshake is completed, the WebSocket connection is closed, which triggers the proxy.on('close', ...) event.

This log message as it is a normal behavior and does not indicate any issue with the proxy server or WebSocket connection.

Pawan Singh
  • 824
  • 6
  • 13
  • Read the docs and enable WebSockets... https://www.npmjs.com/package/http-proxy#proxying-websockets – Marc Feb 26 '23 at 15:35
  • @Marc Thanks for your comment, I have already read it and doing the same thing as per doc, just below that this is mentioned - 'Also you can proxy the websocket requests just calling the ws(req, socket, head) method.', and if you look closely I am following that. – Pawan Singh Feb 26 '23 at 15:41

1 Answers1

0

I got it working to some extent by changing the websocket proxy logic like this ->

proxyServer.on("upgrade", function (req, socket, head) {
  let uiPort = getPortFromUrl(req.url);
  proxy.ws(req, socket, head, {
    target: `ws://localhost:${uiPort}`,
  });
});

and editor seems to be loading fine, but I am still getting -> Client disconnected : (meaning proxy.on('close' .. event is getting triggered) on initial load.

The proxy.on('close', ...) event is getting called because the WebSocket connection is closed by the server. This is a normal behavior as the WebSocket connection is closed after the initial handshake is completed.

When the Theia editor is loaded for the first time, it establishes a WebSocket connection with the server to enable real-time communication. After the initial handshake is completed, the WebSocket connection is closed, which triggers the proxy.on('close', ...) event.

This log message as it is a normal behavior and does not indicate any issue with the proxy server or WebSocket connection.

Pawan Singh
  • 824
  • 6
  • 13