主动Grpc: 主动与被动Grpc的行为有所差异,主动Grpc是客户端主动发起请求,服务端被动响应。主动Grpc提供了挂起/堵塞
和异步
的两种请求方式。
被动Grpc: 被动Grpc则为双向流式实现,客户端与服务端可以同时发送和接收数据。
但是需要客户端对接收的数据进行command
与seq
的配对比较,才能拿到对应请求的数据包。
当Kritor端无法正常处理某个请求,或者请求失败的时候,将会使用Grpc的错误码来返回错误信息。其中大量错误信息的描述通常在status.description
中。
除去Grpc用于保证传输稳定和网络波动的那几个状态码外,Kritor端还会使用以下状态码:
OK (code 0)
: 一切正常。INVALID_ARGUMENT (code 3)
: 参数错误,例如群禁言没提供群号。UNIMPLEMENTED (code 12)
: api不支持,例如协议端不支持使用uid。UNAUTHENTICATED (code 16)
: 未认证,通常是鉴权失败或者越级调用。PERMISSION_DENIED (code 7)
: 权限不足,例如没有权限解除群禁言或者无权使用某个服务。INTERNAL (code 13)
: Kritor内部出现问题,例如数据库连接失败或者其他异常。
我们通过几个简单的Kotlin代码示例来演示如何处理请求错误。
如果需要查看错误码的详细信息,可以查看官方文档。
suspend fun main() {
val channel = ManagedChannelBuilder
.forAddress("localhost", 8080)
.usePlaintext()
.enableRetry() // 允许尝试
.executor(Dispatchers.IO.asExecutor()) // 使用协程的调度器
.build()
val stub = AuthenticationGrpcKt.AuthenticationCoroutineStub(channel)
runCatching {
val rsp = stub.auth(authReq {
account = "1145141919810"
ticket = "A123456"
})
println(rsp.code)
}.onFailure {
// 如果错误,打印错误信息
val status = Status.fromThrowable(it)
println(status) // 直接打印code + cause + description
println(status.code) // 打印错误码
println(status.description) // 打印错误描述
}
}
更多语言请查看Grpc官方错误处理示例。
当Kritor端无法正常处理某个请求,或者请求失败的时候,将会在返回包携带错误信息。其中大量错误信息的描述通常在msg
中。
Kritor推送的返回包将会提供以下状态码:
OK (code 0)
: 一切正常。INVALID_ARGUMENT (code 3)
: 参数错误,例如群禁言没提供群号。UNIMPLEMENTED (code 12)
: api不支持,例如协议端不支持使用uid。UNAUTHENTICATED (code 16)
: 未认证,通常是鉴权失败或者越级调用。PERMISSION_DENIED (code 7)
: 权限不足,例如没有权限解除群禁言或者无权使用某个服务。INTERNAL (code 13)
: Kritor内部出现问题,例如数据库连接失败或者其他异常。
详细信息可以查看,请求包与返回包的定义。
如果需要进行鉴权操作的校验,可以查看鉴权服务。
如果确保ticket
可用,请在每次请求的元数据中携带鉴权ticket
,下面是一个简单的示例:
ContactServiceGrpcKt.ContactServiceCoroutineStub(channel).getProfileCard(profileCardRequest {
uin = 114514
}, Metadata().also {
// 114514就是你的ticket
it.put(Metadata.Key.of("ticket", Metadata.ASCII_STRING_MARSHALLER), "114514")
})
Kritor端将携带ticket
在元数据,发起双向流请求,Bot端作为Server应该去实现一个拦截器或者其它操作已获取鉴权ticket
达到鉴权目的!
Kritor提供了多种接口供客户端调用,包括但不限于以下服务: