grpc - gRPC:如何区分服务器端的双流客户端?
问题描述
在本教程和示例代码onNext()
中,服务器可以在每个流观察者上调用方法,该方法将向与服务器双向流的所有客户端广播消息。但是没有方法可以识别哪个观察者对应哪个客户端。服务器如何将消息推送到特定客户端而不是广播?
根据这个答案,如果客户端 ID 由元数据提供,则可以映射每个观察者。似乎const auto clientMetadata = context->client_metadata();
部分可以解决问题,但我使用的是 Java,而不是 C++。是否有任何 Java 等价物可以在服务器端获取元数据?
解决方案
答案在一定程度上取决于如何识别客户。如果初始请求提供了句柄(如用户名,但未提前注册),那么您可以等待第一个onNext()
:
public StreamObserver<Chat.ChatMessage> chat(StreamObserver<Chat.ChatMessageFromServer> responseObserver) {
return new StreamObserver<Chat.ChatMessage>() {
@Override
public void onNext(Chat.ChatMessage value) {
String userHandle = value.getHandle();
// observers would now be a map, not a set
observers.put(userHandle, responseObserver);
...
假设所有用户都已登录,并在标头中提供一个令牌,如 OAuth。然后,您将使用拦截器对用户进行身份验证,并使用 Context 将其传播到应用程序,如https://stackoverflow.com/a/40113309/4690866中所示。
public StreamObserver<Chat.ChatMessage> chat(StreamObserver<Chat.ChatMessageFromServer> responseObserver) {
// USER_IDENTITY is a Context.Key, also used by the interceptor
User user = USER_IDENTITY.get();
observers.put(user.getName(), responseObserver);
return new StreamObserver<Chat.ChatMessage>() {
...
当标识仅适用于这个 RPC 时,第一个更容易/更好。当标识适用于许多 RPC 时,第二个更容易/更好。
推荐阅读
- c - 在 C 中向 SQLite 表添加时间戳
- android - RxJava:根据 observable 的第一次发射结果将 observable 与 Completable 合并
- java - 如何使用支持 Zip64 的 ScatterZipOutputStream 实现并行 Zip 创建?
- c# - 更新列表中的子项会更新 C# 中的所有项
- r - 根据用户选择更改地图颜色填充
- ios - 用 UIAlertController 替换 UIAlertView
- machine-learning - 了解多元线性回归
- amazon-web-services - Traefik 集群还没有准备好用于生产吗?
- email - Gmail 垃圾邮件文件夹中的邮件登陆
- android - 如何设置确定圆形进度条的辅助颜色