question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Any way to make the gateway listen the same port as the application?

See original GitHub issue

Hi there!

Is there any way to make an equivalent to this classic configuration in nest?

var app = express()
  , server = require('http').createServer(app)
  , io = io.listen(server);

server.listen(3000);

My application has only one gateway and I would like it to use the same port as the main express application.

Thanks a lot! Alex

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:4
  • Comments:13 (5 by maintainers)

github_iconTop GitHub Comments

7reactions
kamilmysliwieccommented, Nov 3, 2017

Hi @alejandroSuch, It’s available from v4.2.0. (just left @WebSocketGateway() empty)

5reactions
bradleyayerscommented, Sep 12, 2017

For now I just wrote my own adapter: (I also use ws rather than socket.io)

class WebSocketAdapter
  implements NestWebSocketAdapter {
  private readonly logger = this.loggingService.create(WebSocketAdapter.name);

  constructor(
    private readonly server: http.Server,
    private readonly path: string,
    private readonly authService: AuthService,
    private readonly loggingService: LoggingService
  ) {}

  public create() {
    return new WebSocket.Server({
      server: this.server,
      path: this.path,
      verifyClient: ({ req }: { req: http.IncomingMessage }) => {
        const jwt = this.getJwtFromRequest(req);
        return (
          jwt && !(this.authService.verifyAndDecode(jwt) instanceof Error)
        );
      }
    });
  }

  public bindClientConnect(
    server: WebSocket.Server,
    callback: (client: Client) => void
  ) {
    server.on("connection", (socket, req) => {
      // Coercion to nonnull and Claims is possible because we provide
      // `verifyClient` to WebSocket.Server.
      const jwt = this.getJwtFromRequest(req);
      const claims = this.authService.skipVerifyAndDecode(jwt!) as Claims;
      const client = new Client(socket, claims);
      callback(client);
    });
  }

  // Explicit `this` preservation due to https://github.com/kamilmysliwiec/nest/issues/150
  public bindClientDisconnect = (
    client: Client,
    callback: (client: Client) => void
  ) => {
    client.ws.on("close", () => {
      callback(client);
    });
  };

  public bindMessageHandlers(
    client: Client,
    handlers: MessageMappingProperties[]
  ) {
    client.ws.on("message", async data => {
      if (typeof data !== "string") {
        this.logger.warn(
          `Received "${typeof data}" message, expected: "string"`
        );
        return;
      }

      let json: { [k: string]: any };

      // Parse
      try {
        json = JSON.parse(data);
      } catch (e) {
        this.logger.error(
          `Error while JSON decoding message`,
          e instanceof Error ? e.stack : undefined
        );
        return;
      }

      // Verify shape
      const type = json["type"];
      if (typeof type !== "string") {
        this.logger.error(
          `Invalid "type" field ("${typeof type}"), expected: "string"`
        );
        return;
      }

      // Find a message handler
      const handler = handlers.find(h => h.message === type);
      if (!handler) {
        this.logger.warn(`Received unknown message "${type}"`);
        return;
      }

      // Execute handler
      try {
        await handler.callback(json);
      } catch (e) {
        this.logger.error(
          `Error occurred during "${type}" handler`,
          e instanceof Error ? (e.stack ? e.stack : e.message) : undefined
        );
        return;
      }
    });
  }

  private getJwtFromRequest(req: http.IncomingMessage): string | null {
    if (req.url) {
      const { query } = url.parse(req.url, true);
      if (query && typeof query.jwt === "string") {
        return query.jwt;
      }
    }
    return null;
  }
}

/**
 * A wrapper to associate claims (from the URL) with a WebSocket. This allows us
 * to know who is connected to each socket.
 */
class Client {
  constructor(public readonly ws: WebSocket, public readonly claims: Claims) {}

  public send(message) {
    this.ws.send(JSON.stringify(message));
  }
}

And then use my own HTTP server:

const express = Express();
const server = http.createServer(express);

express.use(morgan(config.DEBUG ? "dev" : "combined"));
express.use(bodyParser.json());
express.use(cors());
express.use(compression());

const nest = NestFactory.create(ApplicationModule, express);

const environmentService = new EnvironmentService();

nest.useGlobalFilters(new DbErrorFilter(), new JsonValidationErrorFilter());
nest.useWebSocketAdapter(
  new RealtimeGateway.WebSocketAdapter(
    server,
    "/realtime",
    new AuthService(environmentService),
    new LoggingService(environmentService)
  )
);
nest.init();

server.listen(config.PORT, () => {
  new Logger("http").log(`Listening on port ${config.PORT}`);
});
Read more comments on GitHub >

github_iconTop Results From Across the Web

Can two applications listen to the same port? | Pico
The short answer is “no, not on the same host." The longer answer is that this is by design, the basic rationale being...
Read more >
Azure Application Gateway listener configuration
Choose the frontend port. Select an existing port or create a new one. Choose any value from the allowed range of ports. You...
Read more >
Can two applications listen to the same port? - Stack Overflow
For TCP, no. You can only have one application listening on the same port at one time. Now if you had 2 network...
Read more >
How to Configure a Single Secure Gateway/ Web Interface ...
To redirect listening local port 80 / HTTP to port 443 / HTTPS, you must have a redirection page listening on port 80....
Read more >
Setting up HTTPS for myFileGateway - IBM
To run myFileGateway inside your secure network, no configuration is required. ... No two HTTP Server adapter configurations can listen on the same...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found