MetaData
MetaData 功能在 gRPC 里是非常重要。有些场景,我们需要像http header
一样的能力,如链路追踪,调用来源等等场景,这个时候 Metadata 就是满足这些场景的功能。
客户端发送
客户端发送metadata
,需要调用loader.makeMetadata()
,使用方式如下:
const client = clients.get('test.helloworld.Greeter')
const meta = loader.makeMetadata({
'x-cache-control': 'max-age=100',
'x-business-id': ['grpcity', 'testing'],
'x-timestamp-client': 'begin=' + new Date().toISOString()
})
const { status, metadata, response } = await client.sayGreet({ name: 'greeter' }, meta)
console.log(metadata)
我们打印metadata
, 结果如下:
Terminal
Metadata {
internalRepr: Map(8) {
'content-type' => [ 'application/grpc+proto' ],
'x-cache-control' => [ 'max-age=100' ],
'x-business-id' => [ 'grpcity, testing' ],
'x-timestamp-client' => [ 'begin=2023-11-01T03:31:05.942Z' ],
'x-client-hostname' => [ 'ChakhsudeAir' ],
'user-agent' => [ 'grpc-node-js/1.9.7' ],
'x-timestamp-server' => [ 'received=2023-11-01T03:31:06.987Z' ],
'date' => [ 'Wed, 01 Nov 2023 03:31:06 GMT' ]
},
options: {}
}
客户端默认发送以下的 metadata:
x-client-hostname
: 值为操作系统的hostname
;
服务端默认发送以下的 metadata:
content-type
: 值一般为application/grpc+proto
;user-agent
: 值一般为grpc-node-js/1.9.7
;date
: 值一般为Wed, 01 Nov 2023 03:31:06 GMT
;
服务端接收
服务端接收metadata
的位置在 call.metadata
里,使用之前需要先clone()
出来,然后根据key
去get(key)
值。
async sayGreet(call) {
const { name } = call.request
// 获取 call 里的 metadata 信息
const metadata = call.metadata.clone()
// 获取具体的 metadata kv
const cacheAge = metadata.get('x-cache-control')
const businessId = metadata.get('x-business-id')
const clientTimestamp = metadata.get('x-timestamp-client')
// 打印 metadata value
console.log(cacheAge)
console.log(businessId)
console.log(clientTimestamp)
return {
message: `hello ${name || "world"} by Greeter in server1`
}
}
输出结果如下:
Terminal
[ 'max-age=100' ]
[ 'grpcity, testing' ]
[ 'begin=2023-10-31T16:34:22.296Z' ]
服务端发送
有时候,我们也需要服务端把metadata
信息发送返回给客户端的情况,方法如下:
async SayHello (call) {
const metadata = call.metadata.clone()
metadata.add('x-timestamp-server', 'received=' + new Date().toISOString())
call.sendMetadata(metadata)
// 省略...
}
服务端发送metadata
,客户端是可以接收到的。