See the full example here
Dubbo-Python supports streaming calls, including ClientStream
, ServerStream
, and BidirectionalStream
modes.
Streaming calls can be divided into write-streams and read-streams. For ClientStream
, it’s multiple writes with a single read; for ServerStream
, a single write with multiple reads; and BidirectionalStream
allows multiple writes and reads.
Write operations in streaming calls can be divided into single write (ServerStream
) and multiple writes (ClientStream
and BidirectionalStream
).
Single write calls are similar to unary mode. For example:
stub.server_stream(greeter_pb2.GreeterRequest(name="hello world from dubbo-python"))
For multiple writes, users can write data using either an iterator or writeStream
(only one of these options should be used).
Iterator-based Write: Writing via iterator is similar to unary mode, with the main difference being the use of an iterator for multiple writes. For example:
# Use an iterator to send multiple requests
def request_generator():
for i in ["hello", "world", "from", "dubbo-python"]:
yield greeter_pb2.GreeterRequest(name=str(i))
# Call the remote method and return a read_stream
stream = stub.client_stream(request_generator())
Using writeStream
: This method requires an empty argument, after which data is written incrementally using write
, and done_writing
is called to end the write-stream. For example:
stream = stub.bi_stream()
# Use the write method to send messages
stream.write(greeter_pb2.GreeterRequest(name="jock"))
stream.write(greeter_pb2.GreeterRequest(name="jane"))
stream.write(greeter_pb2.GreeterRequest(name="alice"))
stream.write(greeter_pb2.GreeterRequest(name="dave"))
# Call done_writing to notify the server that the client has finished writing
stream.done_writing()
Read operations for streaming calls can be single read (ClientStream
) or multiple reads (ServerStream
and BidirectionalStream
). A ReadStream
is returned in all cases, and data can be read using the read
method or an iterator. When using read
, please note:
read
method supports a timeout
parameter (in seconds).read
method can return one of three values: the expected data, None
(timeout exceeded), or EOF
(end of the read-stream).A single call to the read
method will retrieve the data, for example:
result = stream.read()
print(f"Received response: {result.message}")
Multiple reads can be done by repeatedly calling read
, with handling for None
and EOF
values. Since ReadStream
implements __iter__
and __next__
, an iterator-based approach can also be used, which automatically handles these values but doesn’t support a timeout.
Using Iterator (Recommended):
def client_stream(self, request_iterator):
response = ""
for request in request_iterator:
print(f"Received request: {request.name}")
response += f"{request.name} "
return greeter_pb2.GreeterReply(message=response)
Multiple Calls to read
Method:
# Use read method to receive messages
# If no message arrives within the specified time, returns None
# If the server has finished sending messages, returns EOF
while True:
i = stream.read(timeout=0.5)
if i is dubbo.classes.EOF:
break
elif i is None:
print("No message received")
continue
print(f"Received response: {i.message}")