准备工作
安装nestjs脚手架
npm i -g @nestjs/cli
创建nest项目
1、创建项目并跳过安装依赖
nest new <project_name> --skip-install
2、如果不需要eslint和prettier可以删除相应配置文件以及依赖项,再进行依赖安装
cd <project_name>
npm install
3、配置静态文件目录
npm install @nestjs/serve-static
//app.module.ts
import { Module } from '@nestjs/common';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';
@Module({
imports: [
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..', 'public')
}),
],
controllers: []
})
export class AppModule {}
配置prisma
1、安装依赖
npm install --save-dev prisma
2、初始化数据模型
npx prisma init
编辑prisma/schema.prisma文件,创建数据模型
3、通过数据模型生成数据库表
npx prisma db push
该步骤会自动生成 @prisma/client,如果需要手动生成,可执行该命令
npx prisma generate
配置swagger
1、安装依赖
npm install @nestjs/swagger
2、启用swagger
//main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
//设置OPENAPI接口文档
const config = new DocumentBuilder()
.setTitle('项目名称')
.setDescription('接口描述')
.setVersion('1.0')
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, document);
await app.listen(3000);
}
bootstrap().catch((err) => {
console.log('bootstrap error:', err);
});
配置websocket
1、安装依赖
npm install ws @nestjs/websockets @nestjs/platform-socket.io
npm install --save-dev @types/ws
2、创建websocket适配器
由于nest默认使用socket.io作为websocket适配器,使用原生websocket需要自己创建适配器
//ws.adapter.ts
import { INestApplicationContext, Logger, WebSocketAdapter } from '@nestjs/common';
import { filter, fromEvent, mergeMap, Observable, EMPTY } from 'rxjs';
import { MessageMappingProperties } from '@nestjs/websockets';
import { CloseEvent, WebSocket } from 'ws';
/**
* 原生Websocket适配器
*/
export class WsAdapter implements WebSocketAdapter {
private name: string;
constructor(private app: INestApplicationContext) {}
create(port: number, options?: any): any {
this.name = options.name || 'None';
Logger.log(`\x1b[0mWebsocket Server Listened On ::${port}`, this.name);
return new WebSocket.Server({ port, ...options });
}
bindClientConnect(server: any, callback: (...args: any[]) => any): any {
server.on('connection', callback);
}
bindMessageHandlers(client: WebSocket, handlers: MessageMappingProperties[], transform: (data: any) => Observable<any>): any {
Logger.log(`\x1b[0mWebsocket Client Connected`, this.name);
fromEvent(client, 'message')
.pipe(
mergeMap((data) => this.bindMessageHandler(client, data, handlers, transform)),
filter((result) => result)
)
.subscribe((response) => client.send(JSON.stringify(response)));
fromEvent(client, 'close')
.pipe(
mergeMap((data: CloseEvent) => this.bindCloseHandler(client, data)),
filter((result) => result)
)
.subscribe((response) => client.send(JSON.stringify(response)));
fromEvent(client, 'error')
.pipe(
mergeMap((data: CloseEvent) => this.bindErrorHandler(client, data)),
filter((result) => result)
)
.subscribe((response) => client.send(JSON.stringify(response)));
}
/**
* 定义关闭事件处理方法
*/
bindCloseHandler(client: WebSocket, event: CloseEvent): Observable<any> {
console.log(event.type, event.code, event.reason);
return EMPTY;
}
/**
* 定义错误事件处理方法
*/
bindErrorHandler(client: WebSocket, event: CloseEvent): Observable<any> {
console.log(event);
console.log(event.type, event.code, event.reason);
return EMPTY;
}
/**
* 定义消息事件处理方法
*/
bindMessageHandler(client: WebSocket, buffer: any, handlers: MessageMappingProperties[], transform: (data: any) => Observable<any>): Observable<any> {
let message = null;
try {
message = JSON.parse(buffer.data);
} catch (error) {
Logger.error(`Websocket Client Message Parse Error \x1b[0m${buffer.data}`, this.name);
Logger.error(error, this.name);
return EMPTY;
}
//此处使用`type`值作为消息事件名称
const messageHandler = handlers.find((handler) => handler.message === message.type);
if (!messageHandler) {
return EMPTY;
}
return transform(messageHandler.callback(message));
}
close(server: WebSocket) {
Logger.log(`\x1b[0mWebsocket Server Closed`, this.name);
server.close();
}
}
3、使用适配器
//main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { WsAdapter } from './utils/ws.adapter';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
//设置websocket适配器
app.useWebSocketAdapter(new WsAdapter(app));
await app.listen(3000);
}
bootstrap().catch((err) => {
console.log('bootstrap error:', err);
});
文章作者:DOTATONG
发布日期:2024-04-01
评论