-
Notifications
You must be signed in to change notification settings - Fork 568
/
clients.ts
134 lines (124 loc) 路 3.63 KB
/
clients.ts
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import {
Config,
Init,
Logger,
Provide,
Scope,
ScopeEnum,
Utils,
ILogger,
} from '@midwayjs/core';
import { credentials, loadPackageDefinition } from '@grpc/grpc-js';
import {
DefaultConfig,
IClientOptions,
IGRPCClientServiceOptions,
} from '../interface';
import { finePackageProto, loadProto } from '../util';
import { ClientUnaryRequest } from './type/unary-request';
import { ClientDuplexStreamRequest } from './type/duplex-request';
import { ClientReadableRequest } from './type/readable-request';
import { ClientWritableRequest } from './type/writeable-request';
@Provide('clients')
@Scope(ScopeEnum.Singleton)
export class GRPCClients extends Map {
@Config('grpc')
grpcConfig: DefaultConfig;
@Logger()
logger: ILogger;
@Init()
async initService() {
if (!this.grpcConfig['services']) {
this.logger.debug('Please set gRPC services in your config["grpc"]');
return;
}
for (const cfg of this.grpcConfig['services']) {
await this.createClient(cfg);
}
}
async createClient<T>(options: IGRPCClientServiceOptions): Promise<T> {
const packageDefinition = await loadProto({
loaderOptions: options.loaderOptions,
protoPath: options.protoPath,
});
const allProto = loadPackageDefinition(packageDefinition);
const packageProto: any = finePackageProto(allProto, options.package);
for (const definition in packageDefinition) {
if (!packageDefinition[definition]['format']) {
const serviceName = definition.replace(`${options.package}.`, '');
const connectionService = new packageProto[serviceName](
options.url,
credentials.createInsecure(),
options.clientOptions
);
for (const methodName of Object.keys(packageDefinition[definition])) {
const originMethod = connectionService[methodName];
connectionService[methodName] = (
clientOptions: IClientOptions = {}
) => {
return this.getClientRequestImpl(
connectionService,
originMethod,
clientOptions
);
};
connectionService[Utils.camelCase(methodName)] =
connectionService[methodName];
}
this.set(definition, connectionService);
return connectionService;
}
}
}
getService<T>(serviceName: string): T {
return this.get(serviceName);
}
getClientRequestImpl(client, originalFunction, options = {}) {
const genericFunctionSelector =
(originalFunction.requestStream ? 2 : 0) |
(originalFunction.responseStream ? 1 : 0);
let genericFunctionName;
switch (genericFunctionSelector) {
case 0:
genericFunctionName = new ClientUnaryRequest(
client,
originalFunction,
options
);
break;
case 1:
genericFunctionName = new ClientReadableRequest(
client,
originalFunction,
options
);
break;
case 2:
genericFunctionName = new ClientWritableRequest(
client,
originalFunction,
options
);
break;
case 3:
genericFunctionName = new ClientDuplexStreamRequest(
client,
originalFunction,
options
);
break;
}
return genericFunctionName;
}
}
export const createGRPCConsumer = async <T>(
options: IGRPCClientServiceOptions
): Promise<T> => {
const clients = new GRPCClients();
options.url = options.url || 'localhost:6565';
clients.grpcConfig = {
services: [options],
};
await clients.initService();
return Array.from(clients.values())[0];
};