参考文档:NestJs中文文档-WebSocket
WebSocket网关
要使用WS,必须先加载适配器,Nestjs默认支持两种适配器,socket.io与ws库.因为ws库支持原生的websockets,所以性能上更具优势,所以我们使用ws的适配器
// src/main.ts
import { WsAdapter } from '@nestjs/platform-ws';
async function bootstrap() {
...
app.useWebSocketAdapter(new WsAdapter(app));
await app.listen(3000);
}
bootstrap();
创建Websockets网关
// src/socket-test/socket-test.gateway.ts
import {
WebSocketGateway,
SubscribeMessage,
MessageBody,
ConnectedSocket,
OnGatewayDisconnect
} from "@nestjs/websockets";
import { Socket } from "socket.io";
import { Logger } from "@nestjs/common";
@WebSocketGateway(3002)
export class SocketTestGateway implements OnGatewayDisconnect {
// 在线用户集合
_oneliners: Record<string, any> = {};
handleDisconnect(client: Socket) {
let removeKey = null;
Object.keys(this._oneliners).map(key => {
if (this._oneliners[key] === client) {
removeKey = key;
}
});
delete this._oneliners[removeKey];
Logger.log(`断开连接,userId: ${removeKey}`)
}
// 用户上线
@SubscribeMessage("online")
online(@MessageBody() data: any, @ConnectedSocket() client: Socket) {
this._oneliners[data.sendId] = client;
Logger.log(`用户登录,userId: ${data.sendId}`)
Logger.log(`在线用户: ${Object.keys(this._oneliners)}`)
return { event: "online", data };
}
// 心跳
@SubscribeMessage("heartbeat")
heartbeat() {
return { event: "heartbeat" };
}
// 发送消息
@SubscribeMessage("send")
async send(@MessageBody() data: any) {
this._oneliners[data.receiveId].send(JSON.stringify(
{ event: "receive", data }
));
return { event: "send", data };
}
}
网关写好后别忘了放到提供者中注册,否则无法生效
// src/socket-test/socket-test.module.ts
import { Module } from '@nestjs/common';
import { SocketTestGateway } from './socket-test.gateway';
@Module({
providers: [SocketTestGateway]
})
export class SocketTestModule {}
最后不要忘记在AppModule
中注入SocketTestModule
// src/app.module.ts
import { Module } from "@nestjs/common";
import { SocketTestModule } from "./socket-test/socket-test.module";
@Module({
imports: [
...
SocketTestModule
],
...
})
export class AppModule {
}