Skip to content

Commit 70a428d

Browse files
committed
feat(@142vip/grpc): 支持单例模式,grpc客户端、服务端通用方法
1 parent 4d7172c commit 70a428d

14 files changed

+315
-0
lines changed

packages/grpc/CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5+
6+
## v0.0.1-alpha.0 (2024-07-14)
7+
8+
### ✨ Features
9+
10+
- 新增`tsconfig`配置,统一模块编译 by . @chufan
11+
- 基本结构初始化 by . @chufan

packages/grpc/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# @142vip/grpc
2+
3+
[![NPM version](https://img.shields.io/npm/v/@142vip/grpc?labelColor=0b3d52&color=1da469&label=version)](https://www.npmjs.com/package/@142vip/grpc)
4+
5+
## 证书
6+
7+
[MIT](https://opensource.org/license/MIT)
8+
9+
Copyright (c) 2019-present, 142vip 储凡

packages/grpc/build.config.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { defineBuildConfig } from 'unbuild'
2+
3+
export default defineBuildConfig({
4+
entries: [
5+
'src/index',
6+
],
7+
declaration: true,
8+
clean: true,
9+
rollup: {
10+
emitCJS: true,
11+
inlineDependencies: true,
12+
},
13+
})

packages/grpc/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './src'

packages/grpc/package.json

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"name": "@142vip/grpc",
3+
"version": "0.0.1-alpha.0",
4+
"private": false,
5+
"description": "公众号搜:储凡",
6+
"author": "mmdapl <mmdapl@163.com>",
7+
"license": "MIT",
8+
"homepage": "https://142vip.github.io/core-x/packages/oauth/",
9+
"repository": {
10+
"type": "git",
11+
"url": "git+https://github.com/142vip/core-x.git",
12+
"directory": "packages/grpc"
13+
},
14+
"keywords": [
15+
"公众号搜:储凡",
16+
"142vip",
17+
"@142vip",
18+
"@142vip/grpc",
19+
"grpc"
20+
],
21+
"sideEffects": false,
22+
"exports": {
23+
".": {
24+
"types": "./dist/index.d.ts",
25+
"import": "./dist/index.mjs",
26+
"require": "./dist/index.cjs"
27+
}
28+
},
29+
"main": "./dist/index.mjs",
30+
"module": "./dist/index.mjs",
31+
"types": "./dist/index.d.ts",
32+
"files": [
33+
"dist"
34+
],
35+
"scripts": {
36+
"build": "unbuild",
37+
"typecheck": "tsc --noEmit"
38+
},
39+
"dependencies": {
40+
"@grpc/grpc-js": "^1.12.5",
41+
"@grpc/proto-loader": "^0.7.13"
42+
},
43+
"publishConfig": {
44+
"access": "public",
45+
"registry": "https://registry.npmjs.org"
46+
}
47+
}

packages/grpc/src/grpc-client.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import grpc from '@grpc/grpc-js'
2+
import type { ServiceClient } from '@grpc/grpc-js/build/src/make-client'
3+
import { Singleton } from './singleton'
4+
import type { ServiceClaDefinition } from './grpc.interface'
5+
6+
type GrpcServices = Map<string, ServiceClient>
7+
8+
export class GrpcClient extends Singleton<GrpcClient> {
9+
private readonly grpcServices: GrpcServices
10+
constructor() {
11+
super()
12+
this.grpcServices = new Map<string, ServiceClient>()
13+
}
14+
15+
/**
16+
* 建立连接
17+
*/
18+
public connect(connectUri: string, serviceClaDefinitions: ServiceClaDefinition[]): void {
19+
// 创建服务实例
20+
for (const { packageName, ServiceClass, serviceName } of serviceClaDefinitions) {
21+
console.log(`包:${packageName} -- 类:${serviceName}`)
22+
this.grpcServices.set(serviceName, new ServiceClass(connectUri, grpc.credentials.createInsecure()))
23+
}
24+
}
25+
26+
/**
27+
* 获取连接Service
28+
*/
29+
public getService<T>(serviceName: string): T {
30+
if (!this.grpcServices.has(serviceName)) {
31+
console.log('服务不存在')
32+
throw new Error('服务不存在')
33+
}
34+
return this.grpcServices.get(serviceName) as T
35+
}
36+
37+
/**
38+
* 获取连接数
39+
*/
40+
public getConnectSize(): number {
41+
return this.grpcServices.size
42+
}
43+
44+
/**
45+
* 关闭gRPC连接
46+
*/
47+
public close(): void {
48+
for (const grpcService of this.grpcServices.values()) {
49+
grpcService.close()
50+
}
51+
}
52+
}

packages/grpc/src/grpc-server.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import type { ServiceDefinition, UntypedServiceImplementation } from '@grpc/grpc-js'
2+
import { Server, ServerCredentials } from '@grpc/grpc-js'
3+
import { Singleton } from './singleton'
4+
5+
export class GrpcServer extends Singleton<GrpcServer> {
6+
private readonly server: Server
7+
constructor() {
8+
super()
9+
this.server = new Server()
10+
}
11+
12+
/**
13+
* 添加服务
14+
*/
15+
public addService(service: ServiceDefinition, implementation: UntypedServiceImplementation): void {
16+
this.server.addService(service, implementation)
17+
}
18+
19+
/**
20+
* 移除服务
21+
* @param service
22+
*/
23+
public removeService(service: ServiceDefinition): void {
24+
this.server.removeService(service)
25+
}
26+
27+
/**
28+
* 监听端口,即启动
29+
* @param connectUri
30+
*/
31+
public async listen(connectUri: string): Promise<number> {
32+
return new Promise((resolve, reject) => {
33+
this.server.bindAsync(connectUri, ServerCredentials.createInsecure(), (error, port) => {
34+
// 启动成功
35+
if (error == null) {
36+
console.log('启动成功')
37+
resolve(port)
38+
}
39+
else {
40+
reject(error)
41+
}
42+
})
43+
})
44+
}
45+
}

packages/grpc/src/grpc.interface.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export interface ServiceClaDefinition {
2+
// 构造函数
3+
ServiceClass: any
4+
serviceName: string
5+
packageName: string
6+
}

packages/grpc/src/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export * from './grpc.interface'
2+
export * from './proto-loader'
3+
export * from './grpc-client'
4+
export * from './grpc-server'

packages/grpc/src/proto-loader.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import type protoLoader from '@grpc/proto-loader'
2+
import type { GrpcObject } from '@grpc/grpc-js/build/src/make-client'
3+
import { loadPackageDefinition } from '@grpc/grpc-js'
4+
import { loadSync } from '@grpc/proto-loader'
5+
import { Singleton } from './singleton'
6+
import type { ServiceClaDefinition } from './grpc.interface'
7+
8+
/**
9+
* proto文件加载器
10+
*/
11+
export class ProtoLoader extends Singleton<ProtoLoader> {
12+
private readonly grpcObj: GrpcObject
13+
14+
private readonly protoPath: string
15+
private readonly loaderOptions: protoLoader.Options
16+
17+
constructor(protoPath: string, loaderOptions: protoLoader.Options) {
18+
super(protoPath, loaderOptions)
19+
this.protoPath = protoPath
20+
this.loaderOptions = loaderOptions
21+
22+
this.grpcObj = this.getGrpcObj()
23+
}
24+
25+
public getPackageName(): string {
26+
return Object.keys(this.grpcObj)[0]
27+
}
28+
29+
/**
30+
* 获取rpc Service类定义
31+
*/
32+
public getServiceClassDefinition(): ServiceClaDefinition[] {
33+
const packageName = this.getPackageName()
34+
35+
const services: ServiceClaDefinition[] = []
36+
for (const [serviceName, cla] of Object.entries(this.grpcObj[packageName])) {
37+
if (cla.service != null) {
38+
services.push({
39+
ServiceClass: cla,
40+
serviceName,
41+
packageName,
42+
})
43+
}
44+
}
45+
46+
return services
47+
}
48+
49+
/**
50+
* 加载proto包文件
51+
* @private
52+
*/
53+
private getGrpcObj(): GrpcObject {
54+
const packageDefinition = loadSync(this.protoPath, this.loaderOptions ?? {})
55+
56+
return loadPackageDefinition(packageDefinition)
57+
}
58+
}

0 commit comments

Comments
 (0)