Client
gRPCity 的 clients 工厂会从 loader 里发现 service,对它们建立连接,给你一个像普通 async 函数一样调用的类型化代理。
初始化
const clients = await loader.initClients({ services, channelOptions, credentials })参数:
services(必填)——{ [服务名]: 地址 }服务名:含包名的完整 service 名称。地址:服务端地址,支持host:port字符串或{ host, port }对象两种形态。
channelOptions(可选)—— 透传给底层 gRPC 的 channel 级配置。credentials(可选)—— 客户端凭证,例如 TLS。
示例:
const credentials = loader.makeClientCredentials(rootCerts, privateKey, certChain, verifyOptions)
const clients = await loader.initClients({
services: {
'dev.path.to.serviceA': 'domain.local:9099',
'path.to.serviceB': {
host: '192.168.32.111',
port: 10099
}
},
channelOptions,
credentials
})中间件
clients.use() 会在每次 RPC 前后运行。详见 Client Middleware 指南。
// 逐个添加
clients.use(f1)
clients.use(f2)
clients.use(f3)
// 多个位置参数添加
clients.use(f1, f2, f3)
// 用数组添加
clients.use([f1, f2, f3])中间件只对 async 形式生效。callback 形式会绕过中间件。
获取实例
get(name) 按完整服务名返回一个已缓存的客户端代理。
const serviceAClient = clients.get('dev.path.to.serviceA')
const serviceBClient = clients.get('path.to.serviceB')get() 按名字缓存,重复调用返回同一个实例。如果需要一个全新的、不走缓存的客户端,请使用 getReal()。
发起 RPC 调用
支持两种风格:async 与 callback。常规情况下使用 async。
async
const result = await serviceAClient.rpcMethod(request, metadata, options)参数:
rpcMethod:proto 中 service 定义的方法。共有四种形态:unary、client streaming、server streaming、bidi streaming。request:请求负载,结构由 proto 的 message 类型决定。metadata(可选):作为键值对传递的请求 metadata,常用于鉴权、追踪等。options(可选):per-call 选项对象。可用字段包括timeout(单次调用超时,默认 10 秒)和signal(用于取消调用的AbortSignal,详见 AbortSignal)。
unary 示例:
const meta = loader.makeMetadata({
'x-business-id': ['grpcity', 'testing'],
'x-timestamp-client': 'begin=' + new Date().toISOString()
})
const options = {
timeout: 5000 // 当前时间的 5 秒后超时
}
const { status, peer, metadata, response } = await serviceAClient.rpcMethod(
{ name: 'myapp' },
meta,
options
)每次调用都会返回四个字段:
status:服务端返回的 gRPC status。peer:远端地址。metadata:服务端返回的 trailing metadata。response:响应负载本身。
典型结果:
{
status: {
code: 0,
details: 'OK',
metadata: Metadata { internalRepr: Map(0) {}, options: {} }
},
peer: '::9098',
metadata: Metadata {
internalRepr: Map(2) { 'content-type' => [Array], 'date' => [Array] },
options: {}
},
response: { message: 'hello greeter by Greeter in server1', count: 1 }
}callback
callback 形式挂在 .call. 下:
const a = serviceAClient.call.rpcMethod1({ name: 'myapp' }, (err, result) => {
if (err) throw err
return result
})
const b = serviceBClient.call.rpcMethod2({ name: 'youapp' }, (err, result) => {
if (err) throw err
return result
})重新初始化
服务端地址在运行时发生变化时,先清空已有 clients,再用新映射重新初始化。
const clients = await loader.initClients({
services: {
'dev.path.to.serviceA': 'domain.local:9099',
'path.to.serviceB': { host: '192.168.32.111', port: 10099 }
}
})
clients.clear()
clients.init({
services: {
'dev.path.to.serviceA': 'domain.local:9088',
'path.to.serviceB': { host: '192.168.32.112', port: 10099 }
}
})clear() 必须在 init() 之前。否则后续 init 会拿到缓存工厂,地址切换静默失效。
Last updated on