java - 当我使用 SimpleForwardingServerCallListener 时,gRPC 上下文返回 null
问题描述
我想覆盖(with ) 中的sendMessage
,sendHeaders
, onMessage
,onHalfClose
方法:ServerInterceptor
Context
val context = Context.current().withValue(TestConstants.CONTEXT_KEY, "testValue1")
val delegatedCall = object : SimpleForwardingServerCall<ReqT, RespT>(call) {
override fun sendMessage(message: RespT) {
this@SimpleServerInterceptor.sendMessage(message)
super.sendMessage(message)
}
override fun sendHeaders(headers: Metadata) {
this@SimpleServerInterceptor.sendHeaders(headers)
super.sendHeaders(headers)
}
override fun close(status: Status, trailers: Metadata) {
this@SimpleServerInterceptor.close(status, trailers)
super.close(status, trailers)
}
}
val delegatedListener: ServerCall.Listener<ReqT> =
if (context === null)
next.startCall(delegatedCall, headers)
else
Contexts.interceptCall(context, delegatedCall, headers, next)
return object : ForwardingServerCallListener.SimpleForwardingServerCallListener<ReqT>(delegatedListener) {
override fun onMessage(message: ReqT) {
this@SimpleServerInterceptor.onMessage(message, headers)
super.onMessage(message)
}
override fun onHalfClose() {
this@SimpleServerInterceptor.onHalfClose(headers)
super.onHalfClose()
}
override fun onCancel() {
this@SimpleServerInterceptor.onCancel(headers)
super.onCancel()
}
override fun onComplete() {
this@SimpleServerInterceptor.onComplete(headers)
super.onComplete()
}
override fun onReady() {
this@SimpleServerInterceptor.onReady(headers)
super.onReady()
}
}
这是输出:
>>>>intercept1
>>>>intercept2: testValue1
>>>>onReady1: null
>>>>onMessage1: null
>>>>onHalfClose1: null
HelloService3.hello: testValue1
>>>>sendHeaders2: testValue1
>>>>sendHeaders1: testValue1
>>>>sendMessage2: testValue1
>>>>sendMessage1: testValue1
您可以看到它对( , )Context
有效,但对( , ) 无效。delegatedCall
sendMessage
sendHeaders
delegatedListener
onMessage
onHalfClose
为什么以及如何解决这个问题?
解决方案
我认为问题在于该特定 SimpleForwardingServerCallListener
内容没有看到更改,因为它是在Contexts.interceptCall()
. Listener 用于回调,因此它们由 gRPC 调用。gRPC 将调用返回的侦听器,该侦听器最终将调用delegatedListener
并且delegatedListener
是执行上下文调整的侦听器。Contexts.interceptCall()
根本没有改变call
,所以调用看到上下文的事实意味着监听器必须正常工作。
我建议制作一个ServerCallHandler
执行所有调用SimpleServerInterceptor
并将该处理程序传递给Contexts.interceptCall()
.
(只是一个草图,因为我对 Kotlin 不熟悉)
val context = Context.current().withValue(TestConstants.CONTEXT_KEY, "testValue1")
if (context === null) // Unclear how this will be null
return next.startCall(delegatedCall, headers)
else
return Contexts.interceptCall(context, delegatedCall, headers, new SimpleServerInterceptorHandler(next))
...
// Within SimpleServerInterceptorHandler
val delegatedCall = object : SimpleForwardingServerCall<ReqT, RespT>(call) {
...
}
val delegatedListener: ServerCall.Listener<ReqT> =
next.startCall(delegatedCall, headers)
return object : ForwardingServerCallListener.SimpleForwardingServerCallListener<ReqT>(delegatedListener) {
...
}
推荐阅读
- sql - 删除sql查询中的重复行
- javascript - index.js:66 未捕获的类型错误:无法在 HTMLDivElement 处读取未定义的属性(读取“innerText”)。
(index.js:66) - wordpress - Wordpress 仪表板页面加载进度条
- json - 如何使用 Circe 解码包含 json 的数组
- python - 在 Django 模型中创建多维数组字段
- vue.js - 比 el-tabs 性能更好的多标签页
- node.js - 在 node-postgres 中安排到期时间
- macos - 在 Mac OS El Capitan 上安装和配置 Jenkins
- python - ValueError:基于位置的索引只能具有 [整数、整数切片、整数列表、布尔数组] 类型
- python - Python没有在游戏中注册击键