1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
import { SHARED_SERVICE, SharedService } from '@app/shared';
import { Inject, Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import {
ClientProxy,
ClientProxyFactory,
Ctx,
MessagePattern,
Payload,
RmqContext,
Server,
} from '@nestjs/microservices';
import {
WebSocketGateway,
WebSocketServer,
SubscribeMessage,
MessageBody,
OnGatewayConnection,
OnGatewayDisconnect,
OnGatewayInit,
ConnectedSocket,
} from '@nestjs/websockets';
import { SendMsgDTO } from './dto/send-msg.dto';
import { Socket } from '@nestjs/platform-socket.io';
@Injectable()
@WebSocketGateway(3333, {
cors: {
origin: '*',
},
namespace: 'main',
})
// implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect
export class WSGateway
implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect
{
apiClient: ClientProxy;
clients: Map<string, Socket>; // 存放客户端
constructor(
@Inject(SHARED_SERVICE)
private readonly sharedService: SharedService,
private readonly configService: ConfigService,
) {
console.log('WSGateway constructor: ');
const client: ClientProxy = ClientProxyFactory.create(
sharedService.getRmqOptions(configService.get('API_QUEUE'), ''),
);
this.apiClient = client;
this.clients = new Map<string, Socket>();
}
@WebSocketServer() server: Server;
afterInit(server: any) {
console.log('websocket init:');
this.server = server;
}
handleConnection(socket: Socket) {
console.log('WebSocket client connecting, clients', this.clients.size);
// 生成 socket_id,存储 socket 对象
const socket_id = Math.random().toString(36).substring(7);
socket['socket_id'] = socket_id; // 将socket_id存到客户端socket连接对象中去
this.clients.set(socket_id, socket);
}
handleDisconnect(socket: Socket) {
console.log('WebSocket client disconnected');
// 查找 socket_id,删除 socket 对象
const socket_id = socket['socket_id'];
console.log('remove socket:', socket_id);
this.clients.delete(socket_id);
}
// 订阅客户端发来的send消息: socket.emit('send', data)
@SubscribeMessage('send')
async handleMessage(
@ConnectedSocket()
client: Socket,
@MessageBody() data: SendMsgDTO,
): Promise<number> {
console.log('; got [send]: prompt: ', data.prompt);
// 数据中加入metadata, socket_id表示此消息属于哪个socket,回传的消息带上metadata就知道发给谁了
const metadata = {
socket_id: client['socket_id'],
websocket_service: 'ws-gateway',
};
data['metadata'] = metadata;
this.apiClient.emit({ cmd: 'send' }, data);
return 0;
}
// 此为发送消息给客户端
async emit(socket_id: string, event: any, content: string) {
const client = this.clients.get(socket_id);
const data = JSON.stringify(content);
client.emit('recv', data);
}
}
|