在此tutorial和example code中,服务器可以在每个流观察者上调用onNext()
方法,该方法将 broadcast 消息发送给所有与之进行双流传输的客户端服务器。但是没有方法可以识别哪个观察者对应于哪个客户端。服务器如何将消息推送到特定客户端而不是广播?
根据this answer,如果客户端ID由元数据提供,则可以映射每个观察者。看来const auto clientMetadata = context->client_metadata();
部分可以解决问题,但我使用的是Java,而不是C ++。是否有任何Java等价物可以在服务器端获取元数据?
答案 0 :(得分:1)
答案取决于如何识别客户端。如果初始请求提供了一个句柄(如用户名,但未提前注册),那么您可以等待第一个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时,第二种方法更容易/更简单。