Nest.js 中特定路由上的 WebSockets
Posted
技术标签:
【中文标题】Nest.js 中特定路由上的 WebSockets【英文标题】:WebSockets on specific route in Nest.js 【发布时间】:2019-11-04 01:35:58 【问题描述】:我想创建仅用于 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() );
这里是EventGateway
和EventModule
:
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
进行服务器-客户端通信的控制器?
【问题讨论】:
【参考方案1】:Websocket 在服务器上运行,而不是端点。因此,您不能让它监听特定路由下的请求,而只是一个端口,对于 Nest 的默认配置恰好与 HTTP 相同。
您可以使用像 nginx 这样的反向代理将请求重定向到面向 Websocket 服务器的/api/events
,并且还可以处理重定向到index.html
,甚至无需更改 Websocket 服务器的端口。那么你根本不需要FrontendMiddleware
类。这也更好,因为应用程序不承担管理请求重定向的负担。
【讨论】:
【参考方案2】:是的,可以在另一条路径上创建 WebsocketGateway。您可以只使用 WebsocketGateway 的选项来配置底层 IO-Connection:
例如:
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-Connection
请记住在您的客户端中也更改连接路径。它不再是默认的 /socket.io 路径,而是您的示例中的 /api/events 。
【讨论】:
以上是关于Nest.js 中特定路由上的 WebSockets的主要内容,如果未能解决你的问题,请参考以下文章
如何将所有路由重定向到nest.js中的index.html(Angular)?