Gateway 是用@WebSocketGateway() 装饰的类。Gateway 的内部使用了 socket.io,不过你也可以使用其它的库,比如原生的 Web sockets。Gateway 就像是一个简单的 provider,你可以通过构造方法给它注入依赖,你也可以在其它的类里面注入使用 gateway 。
安装
先得安装需要的包:
npm install @nestjs/websockets @nestjs/platform-socket.io --save npm install @types/socket.io --save-dev
预览
一般情况下,每个 gateway 监听的端口跟 HTTP 服务器用的端口一样,除非你的应用不是一个 Web 应用,或者你修改了端口。你可以给 @WebSocketGateway 装饰器提供一个参数,比如 @WebSocketGateway(80),这里的 80 就是选择使用的端口。你还可以设置 gateway 使用的 namespace 。
@WebSocketGateway(80, { namespace: 'events' })
确保 gateway 运行,需要把它放在一个 providers 数组里。
除了 namespace 选项,还有一些选项,参考 Socket.io 文档。这些选项会在实例化过程中传递给 socket 构造方法。
@WebSocketGateway(80, { transport: ['websocket'] })
Gateway 现在已经开始监听,但还没有订阅信息,下面可以创建一个处理器,它会订阅到 events 信息,并且会响应给用户同样的数据。
events.gateway.ts
@SubscribeMessage('events') handleEvent(client: Client, data: string): string { return data; }
handleEvent() 支持两个参数,第一个是平台特定的 socket 实例,第二个参数是从客户端那里得到的数据。得到了通过网络传递过来的信息以后,handleEvent 会把这个信息发送回去。
还可以使用特定库提供的方法 emit 信息,比如使用 client.emit() 方法,不过这种情况不能使用拦截器。如果不想做出响应,可以不返回任何东西,或者返回 undefined。
在客户端 emit 信息:
socket.emit('events', { name: 'Nest' });
会执行 handleEvent() 方法。在客户端如果要监听上面处理器 emit 的信息,需要附加对应的监听器:
socket.emit('events', { name: 'Nest' }, data => console.log(data));
多响应
Acknowledgment 会被指派一次,而且不支持原生 WebSocket,解决这个限制,可以返回一个包含两个属性的对象,event 是 emit 的事件,data 是转给客户端的数据。
@SubscribeMessage('events') handleEvent(client: Client, data: unknown): WsResponse<unknown> { const event = 'events'; return { event, data }; }
要监听响应,在客户端需要应用一个事件监听器。
socket.on('events', data => console.log(data));
异步响应
信息处理器可以是同步的也可以是异步的,你可以返回 Promise,也可以是 Observable,也就是你可以返回多个值,stream 完成以后会 emit 它们。
events.gateway.ts
@SubscribeMesasge('events') onEvent( client: Client, data: unknown ): Observable<WsResponse<number>> { const event = 'events'; const response = [1, 2, 3]; return from(response).pipe( map(data => ({ event, data })), ); }
上面这个信息处理器会响应 3 次。
生命周期钩子
- OnGatewayInit
- OnGatewayConnection
- OnGatewayDisconnect
服务器
如果需要访问服务实例,可以使用 @WebSocketServer() 装饰器。
@WebSocketServer() server: Server;
server 属性就是服务实例。
评论
为什么我获取不到 WebSocketGateway
4 年 11 个月 以前