3. Client Streaming RPC (поток запросов от клиента)
Теперь наоборот — клиент отправляет поток запросов, а сервер отвечает одним итоговым сообщением.
Клиент → (много запросов) → Сервер
Сервер → (один ответ) → Клиент
Это удобно, когда клиенту нужно собрать несколько событий или пакетов данных и отправить их вместе.
Пример .proto
Сервер (Java)
Клиент
Где применяется:
Отправка файлов по частям.
Отчёты, собираемые из нескольких частей.
Потоковое логирование от клиента на сервер.
#Java #middle #gRPC #proto
Теперь наоборот — клиент отправляет поток запросов, а сервер отвечает одним итоговым сообщением.
Клиент → (много запросов) → Сервер
Сервер → (один ответ) → Клиент
Это удобно, когда клиенту нужно собрать несколько событий или пакетов данных и отправить их вместе.
Пример .proto
service UploadService {
rpc UploadPhotos (stream PhotoChunk) returns (UploadStatus);
}
message PhotoChunk {
bytes content = 1;
}
message UploadStatus {
string message = 1;
}Сервер (Java)
public class UploadServiceImpl extends UploadServiceGrpc.UploadServiceImplBase {
@Override
public StreamObserver<PhotoChunk> uploadPhotos(StreamObserver<UploadStatus> responseObserver) {
return new StreamObserver<PhotoChunk>() {
int totalBytes = 0;
@Override
public void onNext(PhotoChunk chunk) {
totalBytes += chunk.getContent().size();
}
@Override
public void onError(Throwable t) {
System.err.println("Upload failed: " + t.getMessage());
}
@Override
public void onCompleted() {
UploadStatus status = UploadStatus.newBuilder()
.setMessage("Uploaded " + totalBytes + " bytes")
.build();
responseObserver.onNext(status);
responseObserver.onCompleted();
}
};
}
}Клиент
StreamObserver<PhotoChunk> requestObserver = asyncStub.uploadPhotos(
new StreamObserver<UploadStatus>() {
@Override
public void onNext(UploadStatus status) {
System.out.println(status.getMessage());
}
@Override
public void onError(Throwable t) {}
@Override
public void onCompleted() {}
}
);
// Отправляем несколько чанков
requestObserver.onNext(PhotoChunk.newBuilder().setContent(ByteString.copyFrom(new byte[1000])).build());
requestObserver.onNext(PhotoChunk.newBuilder().setContent(ByteString.copyFrom(new byte[500])).build());
requestObserver.onCompleted();
Где применяется:
Отправка файлов по частям.
Отчёты, собираемые из нескольких частей.
Потоковое логирование от клиента на сервер.
#Java #middle #gRPC #proto
👍1
4. Bidirectional Streaming RPC (двунаправленный поток)
Самый мощный и сложный тип.
Клиент и сервер одновременно отправляют данные потоками.
Они не ждут завершения друг друга — общение идёт асинхронно в обе стороны.
Клиент ⇄ (двунаправленный поток) ⇄ Сервер
Пример .proto
Сервер (Java)
Клиент
Где применяется:
Чаты и видеоконференции.
Онлайн-игры и взаимодействие в реальном времени.
Телеметрия, двунаправленные датчики, IoT.
Главная особенность: оба канала открыты, и клиент, и сервер могут посылать данные независимо друг от друга.
5. Под капотом
Все типы RPC работают поверх HTTP/2, где каждый поток — это отдельный канал в рамках одного TCP-соединения.
gRPC использует этот механизм для организации стримов.
По сути, StreamObserver в Java — это высокоуровневая абстракция над HTTP/2-стримом, обеспечивающая асинхронность и реактивное взаимодействие.
#Java #middle #gRPC #proto
Самый мощный и сложный тип.
Клиент и сервер одновременно отправляют данные потоками.
Они не ждут завершения друг друга — общение идёт асинхронно в обе стороны.
Клиент ⇄ (двунаправленный поток) ⇄ Сервер
Пример .proto
service ChatService {
rpc Chat (stream ChatMessage) returns (stream ChatMessage);
}
message ChatMessage {
string user = 1;
string text = 2;
}Сервер (Java)
public class ChatServiceImpl extends ChatServiceGrpc.ChatServiceImplBase {
@Override
public StreamObserver<ChatMessage> chat(StreamObserver<ChatMessage> responseObserver) {
return new StreamObserver<ChatMessage>() {
@Override
public void onNext(ChatMessage message) {
// Эхо-сообщение обратно клиенту
ChatMessage reply = ChatMessage.newBuilder()
.setUser("Server")
.setText("Echo: " + message.getText())
.build();
responseObserver.onNext(reply);
}
@Override
public void onError(Throwable t) {
System.err.println("Error: " + t.getMessage());
}
@Override
public void onCompleted() {
responseObserver.onCompleted();
}
};
}
}Клиент
StreamObserver<ChatMessage> requestObserver = asyncStub.chat(
new StreamObserver<ChatMessage>() {
@Override
public void onNext(ChatMessage value) {
System.out.println(value.getUser() + ": " + value.getText());
}
@Override
public void onError(Throwable t) {}
@Override
public void onCompleted() {}
}
);
requestObserver.onNext(ChatMessage.newBuilder().setUser("Client").setText("Hello!").build());
requestObserver.onNext(ChatMessage.newBuilder().setUser("Client").setText("How are you?").build());
requestObserver.onCompleted();
Где применяется:
Чаты и видеоконференции.
Онлайн-игры и взаимодействие в реальном времени.
Телеметрия, двунаправленные датчики, IoT.
Главная особенность: оба канала открыты, и клиент, и сервер могут посылать данные независимо друг от друга.
5. Под капотом
Все типы RPC работают поверх HTTP/2, где каждый поток — это отдельный канал в рамках одного TCP-соединения.
gRPC использует этот механизм для организации стримов.
По сути, StreamObserver в Java — это высокоуровневая абстракция над HTTP/2-стримом, обеспечивающая асинхронность и реактивное взаимодействие.
#Java #middle #gRPC #proto
👍2
Что выведет код?
#Tasks
import java.util.TreeMap;
public class Task061125 {
public static void main(String[] args) {
TreeMap<Integer, String> map = new TreeMap<>();
map.put(1, "one");
map.put(3, "three");
map.put(5, "five");
map.put(7, "seven");
System.out.print(map.lowerKey(4) + " ");
System.out.print(map.floorKey(4) + " ");
System.out.print(map.higherKey(4) + " ");
System.out.print(map.ceilingKey(4));
}
}
#Tasks
👍1
👍1
Вопрос с собеседований
Что такое шаблон Singleton?🤓
Ответ:
Singleton гарантирует, что класс имеет только один экземпляр.
В Java часто реализуют через enum, так как это потокобезопасно и защищено от сериализации.
Используется для глобальных конфигураций, логгеров, кэшей, соединений.
#собеседование
Что такое шаблон Singleton?
Ответ:
Singleton
В Java часто реализуют через enum, так как это потокобезопасно и защищено от сериализации.
Используется для глобальных конфигураций, логгеров, кэшей, соединений.
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2