lrf 2 years ago
parent
commit
a7e684f3c8

+ 2 - 0
package.json

@@ -16,6 +16,7 @@
     "@midwayjs/swagger": "^3.9.9",
     "@midwayjs/typegoose": "^3.9.0",
     "@midwayjs/validate": "^3.0.0",
+    "@midwayjs/ws": "^3.9.0",
     "@typegoose/typegoose": "^10.0.0",
     "amqp-connection-manager": "^4.1.10",
     "amqplib": "^0.10.3",
@@ -33,6 +34,7 @@
     "@types/koa": "^2.13.4",
     "@types/lodash": "^4.14.191",
     "@types/node": "14",
+    "@types/ws": "^8.5.4",
     "cross-env": "^6.0.0",
     "jest": "^29.2.2",
     "mwts": "^1.0.5",

+ 3 - 0
src/config/config.local.ts

@@ -8,6 +8,9 @@ export default {
     port: 12214,
     globalPrefix: '/dev/point/chat/v1/api',
   },
+  webSocket: {
+    clientTracking: true,
+  },
   swagger: {
     swaggerPath: '/dev/point/chat/v1/api/doc/api',
   },

+ 3 - 0
src/config/config.prod.ts

@@ -9,6 +9,9 @@ export default {
     port: 12214,
     globalPrefix: '/dev/point/chat/v1/api',
   },
+  webSocket: {
+    path: '/dev/point/chat/v1/api/ws',
+  },
   swagger: {
     swaggerPath: '/dev/point/chat/v1/api/doc/api',
   },

+ 2 - 0
src/configuration.ts

@@ -11,6 +11,7 @@ import * as axios from '@midwayjs/axios';
 import { Inject } from '@midwayjs/core';
 import * as rabbitmq from '@midwayjs/rabbitmq';
 import { Context } from '@midwayjs/koa';
+import * as ws from '@midwayjs/ws';
 @Configuration({
   imports: [
     FreeFrame,
@@ -19,6 +20,7 @@ import { Context } from '@midwayjs/koa';
     axios,
     swagger,
     rabbitmq,
+    ws,
     {
       component: info,
       enabledEnvironment: ['local'],

+ 6 - 1
src/controller/chatRecord.controller.ts

@@ -19,6 +19,7 @@ import * as dayjs from 'dayjs';
 import { RoomService } from '../service/room.service';
 import get = require('lodash/get');
 import { MqSender } from '../service/mq/mqSender.service';
+import { WsSocketController } from '../socket/ws.controller';
 @ApiTags(['聊天记录'])
 @Controller('/chatRecord')
 export class ChatRecordController extends BaseController {
@@ -30,6 +31,10 @@ export class ChatRecordController extends BaseController {
 
   @Inject()
   mqSender: MqSender;
+
+  @Inject()
+  ws: WsSocketController;
+
   @Post('/')
   @Validate()
   @ApiResponse({ type: CreateVO_chatRecord })
@@ -68,7 +73,7 @@ export class ChatRecordController extends BaseController {
     let receiver;
     if (get(room, 'customer') === get(data, 'speaker')) receiver = get(room, 'shop');
     else receiver = get(room, 'customer');
-    await this.mqSender.toSendMsg(receiver, data);
+    await this.ws.toSend({ ...result, type: 'chat' }, receiver);
     return result;
   }
   @Get('/')

+ 12 - 2
src/controller/home.controller.ts

@@ -1,9 +1,19 @@
-import { Controller, Get } from '@midwayjs/decorator';
-
+import { Body, Controller, Get, Inject, Post } from '@midwayjs/decorator';
+import { SendMsgDTO } from '../interface/websocket.interface';
+import { WsSocketController } from '../socket/ws.controller';
 @Controller('/')
 export class HomeController {
+  @Inject()
+  ws: WsSocketController;
   @Get('/')
   async home(): Promise<string> {
     return 'Hello Midwayjs!';
   }
+
+  @Post('/sendWebSocket')
+  async sendWebSocket(@Body() object: SendMsgDTO) {
+    const { recevier, ...others } = object;
+    await this.ws.toSend(others, recevier);
+    return 'ok';
+  }
 }

+ 11 - 0
src/interface/websocket.interface.ts

@@ -0,0 +1,11 @@
+import { ApiProperty } from '@midwayjs/swagger';
+import { Rule, RuleType } from '@midwayjs/validate';
+
+export class SendMsgDTO {
+  @ApiProperty({ description: '接收人' })
+  @Rule(RuleType['string']().required())
+  'recevier': string = undefined;
+  @ApiProperty({ description: '消息类型' })
+  @Rule(RuleType['string']().required())
+  'type': string = undefined;
+}

+ 66 - 0
src/socket/ws.controller.ts

@@ -0,0 +1,66 @@
+import { App, Inject, OnWSConnection, OnWSDisConnection, OnWSMessage, WSController } from '@midwayjs/decorator';
+import { Context } from '@midwayjs/ws';
+import * as http from 'http';
+import get = require('lodash/get');
+import { Application } from '@midwayjs/ws';
+import last = require('lodash/last');
+@WSController('*/ws/*')
+export class WsSocketController {
+  @Inject()
+  ctx: Context;
+  @App('webSocket')
+  wsApp: Application;
+
+  @OnWSConnection()
+  async onConnectionMethod(socket: Context, request: http.IncomingMessage) {
+    const url = get(request, 'url');
+    const arr = url.split('/');
+    const token = last(arr);
+    socket.send('connect success');
+    const acs = this.getClients();
+    // 最后一个是该websocket实例,赋上token
+    const client = last(acs);
+    client.token = token;
+  }
+
+  // 获取信息
+  @OnWSMessage('message')
+  async gotMessage(data: Buffer) {
+    // const msg = data.toString();
+  }
+
+  @OnWSDisConnection()
+  async disconnect(id) {
+    // 断开连接
+  }
+  /**
+   * 给指定对象发送消息
+   * @param data 要发送的数据
+   * @param token 店铺id/用户id
+   */
+  async toSend(data: object, token) {
+    const clients = this.getClient(token);
+    if (!clients) return;
+    clients.send(JSON.stringify(data));
+  }
+  /**
+   * 获取所有连接实例
+   */
+  getClients(): Array<any> {
+    const acs = [];
+    const clients = this.wsApp.clients;
+    clients.forEach(e => {
+      acs.push(e);
+    });
+    return acs;
+  }
+  /**
+   * 获取指定实例连接
+   * @param token 用户id/店铺id
+   */
+  getClient(token: string) {
+    const clients = this.getClients();
+    const client = clients.find(f => f.token === token);
+    return client;
+  }
+}