ws.controller.ts 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import { App, Inject, OnWSConnection, OnWSDisConnection, OnWSMessage, WSController } from '@midwayjs/decorator';
  2. import { Context } from '@midwayjs/ws';
  3. import * as http from 'http';
  4. import get = require('lodash/get');
  5. import group = require('lodash/group');
  6. import { Application } from '@midwayjs/ws';
  7. import last = require('lodash/last');
  8. import { Types } from 'mongoose';
  9. const ObjectId = Types.ObjectId;
  10. import { NeedSend } from '../entity/chat/needSend.entity';
  11. import { ReturnModelType } from '@typegoose/typegoose';
  12. import { InjectEntityModel } from '@midwayjs/typegoose';
  13. @WSController('*/ws/*')
  14. export class WsSocketController {
  15. @Inject()
  16. ctx: Context;
  17. @App('webSocket')
  18. wsApp: Application;
  19. @InjectEntityModel(NeedSend)
  20. model: ReturnModelType<typeof NeedSend>;
  21. @OnWSConnection()
  22. async onConnectionMethod(socket: Context, request: http.IncomingMessage) {
  23. const url = get(request, 'url');
  24. const arr = url.split('/');
  25. const token = last(arr);
  26. socket.send('connect success');
  27. const acs = this.getClients();
  28. // 最后一个是该websocket实例,赋上token
  29. const client = last(acs);
  30. client.token = token;
  31. await this.checkNeedSend(client);
  32. }
  33. /**
  34. * 给对象补发 未发送出去的消息
  35. * @param client ws连接实例
  36. */
  37. async checkNeedSend(client) {
  38. const to = get(client, 'token');
  39. if (!to) return;
  40. let list = await this.model.find({ to }).lean();
  41. list = list.map(i => ({ ...i, type: get(i, 'msg.type') }));
  42. const groups = group(list, 'type');
  43. for (const key in groups) {
  44. const list = groups[key];
  45. const type = get(last(list), 'type');
  46. await this.toSend({ type }, to);
  47. }
  48. await this.model.deleteMany({ to });
  49. }
  50. // 获取信息
  51. @OnWSMessage('message')
  52. async gotMessage(data: Buffer) {
  53. // const msg = data.toString();
  54. return '(╯‵□′)╯︵┻━┻';
  55. }
  56. @OnWSDisConnection()
  57. async disconnect(id) {
  58. // 断开连接
  59. }
  60. /**
  61. * 给指定对象发送消息
  62. * @param data 要发送的数据
  63. * @param token 店铺id/用户id
  64. */
  65. async toSend(data: object, token) {
  66. const clients = this.getClient(token);
  67. if (!clients) {
  68. // 存储到待发送表中
  69. await this.model.create({ to: token, msg: data });
  70. return;
  71. }
  72. clients.send(JSON.stringify(data));
  73. }
  74. /**
  75. * 获取所有连接实例
  76. */
  77. getClients(): Array<any> {
  78. const acs = [];
  79. const clients = this.wsApp.clients;
  80. clients.forEach(e => {
  81. acs.push(e);
  82. });
  83. return acs;
  84. }
  85. /**
  86. * 获取指定实例连接
  87. * @param token 用户id/店铺id
  88. */
  89. getClient(token: string) {
  90. const clients = this.getClients();
  91. const client = clients.find(f => new ObjectId(f.token).equals(token));
  92. return client;
  93. }
  94. }