Skip to content
文档
Metadata

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()出来,然后根据keyget(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,客户端是可以接收到的。