Nest.js中特定路由上的WebSockets

时间:2019-06-21 08:13:56

标签: websocket controller nestjs

我想创建仅用于WebSocket(/api/events)的特定API路由,但是在所有在Nest.js上实现WebSockets的示例中,我偶然发现模块已导入AppModule和客户端中正在向根URL发出事件,因为我有这个中间件,所以我不能这样做;

frontend.middleware.ts

import { Request, Response } from 'express';
import { AppModule } from '../../app.module';

export function FrontendMiddleware(
  req: Request,
  res: Response,
  next: Function,
) {
  const { baseUrl } = req;
  if (baseUrl.indexOf('/api') === 0) {
    next();
  } else {
    res.sendFile('index.html', { root: AppModule.getStaticAssetsRootPath() });
  }
}

这里是EventGatewayEventModule

event.gateway.ts

import {
  SubscribeMessage,
  WebSocketGateway,
  WebSocketServer,
  WsResponse,
} from '@nestjs/websockets';
import { from, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Client, Server } from 'socket.io';

@WebSocketGateway({ namespace: 'events' })
export class EventGateway {
  @WebSocketServer()
  server: Server;

  @SubscribeMessage('events')
  findAll(client: Client, data: any): Observable<WsResponse<number>> {
    return from([1, 2, 3]).pipe(map(item => ({ event: 'events', data: item })));
  }

  @SubscribeMessage('identity')
  async identity(client: Client, data: number): Promise<number> {
    return data;
  }
}

event.module.ts

import { Module } from '@nestjs/common';
import { EventGateway } from './event.gateway';

@Module({
  components: [EventGateway],
})
export class EventModule {}

是否有一种创建控制器的方法,该控制器将允许通过/api/events进行服务器-客户端通信?

2 个答案:

答案 0 :(得分:0)

Websocket在服务器而不是端点上运行。因此,您不能让它侦听特定路由下的请求,而只能侦听端口(对于Nest,默认端口恰好与HTTP相同)。

您可以使用Nginx之类的反向代理将请求重定向到面向Websocket服务器的func azure functionapp publish myfunctionapp --publish-local-settings -i,还可以处理重定向到/api/events的情况,甚至不更改Websocket服务器的端口。然后,您根本不需要index.html类。这样也更好,因为该应用程序不承担管理请求重定向的负担。

答案 1 :(得分:0)

是的,可以在其他路径上创建WebsocketGateway。您可以只使用WebsocketGateway的选项来配置基础IO连接:

例如:

import {
  SubscribeMessage,
  WebSocketGateway,
  WebSocketServer,
  WsResponse,
} from '@nestjs/websockets';
import { from, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Client, Server } from 'socket.io';

@WebSocketGateway({ path: '/api/events', namespace: 'events' })
export class EventGateway {
  @WebSocketServer()
  server: Server;

  @SubscribeMessage('events')
  findAll(client: Client, data: any): Observable<WsResponse<number>> {
    return from([1, 2, 3]).pipe(map(item => ({ event: 'events', data: item })));
  }

  @SubscribeMessage('identity')
  async identity(client: Client, data: number): Promise<number> {
    return data;
  }
}

这将在http://localhost/api/events上启动IO连接

请记住,也要在客户端中更改连接路径。它不再是默认的/socket.io路径,而是示例中的/ api / events。