title: How to handle a bidirectional grpc stream asynchronously
body: <p>I have a game or for that matter any remote user interface with a server and multiple clients which should communicate via network.
  <strong>Both</strong> client and server should be able to send updates <strong>asynchronously</strong>.</p>
  <p>This seems to be a very natural service definition, which let's grpc manage sessions.</p>
  <pre><code>syntax = &quot;proto3&quot;;
  
  package mygame;
  
  service Game {
      rpc participate(stream ClientRequest) returns (ServerResponse);
  }
  
  message ClientRequest {
      // Fields for the initial request and further updates
  }
  
  message ServerResponse {
      // Game updates
  }
  </code></pre>
  <p>Implementing the client is trivial (although the following code is obviously incomplete and simplified).</p>
  <pre class="lang-py prettyprint-override"><code>class Client:
      def __init__(self):
          self.channel = grpc.insecure_channel(&quot;localhost:50051&quot;)
          self.stub = game_pb2_grpc.GameStub(channel)
          self.output_queue = queue.Queue()
  
      def output_iter(self):
          while True:
              client_output_msg = self.output_queue.get()
              self.output_queue.task_done()
              yield client_output_msg
  
      def do_work(self):
          for response in self.stub.participate(self.output_iter()):
              print(response)  # handle update
  
  
  with grpc.insecure_channel(&quot;localhost:50051&quot;) as channel:
      client = Client()
      client.do_work()
  </code></pre>
  <p>What seems hard is implementing the server without blocking.</p>
  <pre class="lang-py prettyprint-override"><code>class Game(game_pb2_grpc.GameServicer):
      def __init__(self):
          self.pending_events = queue.Queue()
  
      def participate(self, request_iter, context):
          for client_update in request_iter:
              print(client_update)
              # !!!
              # The next bit won't happen if the client has no updates
              # !!!
              try:
                  while True:
                      server_update = self.pending_events.get_nowait()
                      yield server_update
              except queue.Empty:
                  pass
  
  server = grpc.server(ThreadPoolExecutor(max_workers=100))
  game_pb2_grpc.add_GameServicer_to_server(Game(), server)
  server.add_insecure_port(&quot;[::]:50051&quot;)
  server.start()
  server.wait_for_termination()
  </code></pre>
  <p>As commented in the code, the client won't receive updates if it doesn't constantly send requests.
  Maybe a async approach would be better, which might also solve other problems in this design.</p>
  <p>PS: This issue has been solved with grpc in go <a href="https://mortenson.coffee/blog/making-multiplayer-game-go-and-grpc/" rel="nofollow noreferrer">here</a>, however i don't see how to translate this to pythons grpc implementations.</p>
  <p>I would be very happy about any help!</p>