Angular Universal (ssr-dev-server) Setting or getting the random port of the express app in dev:ssr

Viewed 33

I am trying to call a websocket server in an express app in Angular Universal.


It works fine in production when using npm run serve:ssr

> my-app@0.0.0 serve:ssr
> node dist/evaluator/server/main.js

Node Express app listening on http://localhost:4000

I can call the websocket at ws://localhost:4000


However in local development mode with npm run dev:ssr

This following line of code in the builder

https://github.com/angular/universal/blob/main/modules/builders/src/ssr-dev-server/utils.ts#L22

export function getAvailablePort(): Promise<number> {
  return new Promise((resolve, reject) => {
    const server = createServer();
    server
      .unref()
      .on('error', reject)
      .listen(0, () => {
        const { port } = server.address() as AddressInfo;
        server.close(() => resolve(port)); // This port is random
      });
  });
}

sets a random port affecting on the fly process.env['PORT'] for the express server (SSR).

code in server.ts (express server side)


export function app(): express.Express {
  const express_app = express();
  // ....
  return express_app;
}

function run(): void {
  const port = process.env['PORT'] || 4000; // that process port comes from the above builder utils

  // Start up the Node app
  const express_app = app();
  const server = http.createServer(express_app);
  const wss = new WebSocketServer({ server });

  wss.on('connection', (ws) => {
    ws.on('message', (message) => {
      ws.send(JSON.stringify('mess ' + message));
    });
  });
  server.listen(port, () => {
    console.log(`Node Express app listening on http://localhost:${port}`);
  });
}

This comment states that you can set the port by config

https://github.com/angular/universal/issues/1628#issuecomment-616322722

but it seems to me that there is a confusion with the angular default 4200 port (that you can set in angular.json, as states the doc https://github.com/angular/universal/blob/main/modules/builders/README.md#ssr-dev-server) but it does not affect the express server port which is always random.

If I force the port to 4000 in /node_modules/@nguniversal/builders/src/ssr-dev-server/utils.jsL27 then the express app starts on port 4000 then I can proxy the request in proxy.conf.json with for instance

{
  "/ws": {
    "target": "ws://localhost:4000",
    "secure": false,
    "ws": true
  }
}

otherwise I don't know how I can get that dynamic port to request the websocket. It seems the proxy magic af Angular Universal only proxy http://localhost:4200/ to the express router and not ws://localhost:4200/ also. So the only way I can request the websocket is by proxying ws://localhost:4200/ws to ws://localhost:4000/

My code in app.component.ts (angular frontend side)

  constructor(
    @Inject(PLATFORM_ID) private platformId: InjectionToken<Record<string, unknown>>,
    @Inject(DOCUMENT) private document: Document
  ) {
    this.window = this.document.defaultView as Window;
    if (this.isBrowser) {
      const myWebSocket = webSocket(this.window.location.href.replace('http', 'ws')); 
    
    // open a socket to ws://localhost:4200/

    // so here the PORT is not correct ws://localhost:4200/ does not reply 
    // because the port is dynamicaly set unless I hard fix it to 4000 in utils 
    // and set it here too instead of Angular 4200 port

      myWebSocket.asObservable().subscribe(dataFromServer => {
        console.log(dataFromServer);
      });
      myWebSocket.next(JSON.stringify({}));
    }

My question is how can I set this port or how can get this dynamic process.env['PORT'] on angular side ?

Compiled successfully.
Node Express app listening on http://localhost:43481 // How can I set this port ? or how can I get it in app component

** Angular Universal Live Development Server is listening on http://localhost:4200, open your browser on http://localhost:4200 **

Related :

WebSocket with angular universal

https://github.com/angular/universal/issues/1848

https://github.com/angular/universal/issues/1722

Thanks for reading

0 Answers
Related