2017-05-19 11 views
2

チャットのようなアプリケーションを作成したいとしましょう。クライアントはテキストをサーバーに送信することができ、その逆もあります。テキスト交換の順序は任意です。GRPCストリーミングセレクト(Python)

サーバーは、サーバーの応答ストリームを制御する別のストリームに依存します。 GRPCストリームはPythonジェネレータとして公開されています。サーバーは、クライアントの入力と同時に他のストリームの入力を待つことができますか?通常はselect()のようなものを使用しますが、ここではジェネレータがあります。

私は、望ましい動作を実装するいくつかのサンプルコードを持っていますが、クライアントとサーバー側に追加のスレッドが必要です。スレッドなしで同じ結果を得るにはどうすればよいですか?

プロト:

syntax = 'proto3'; 

service Scenario { 
    rpc Chat(stream DPong) returns (stream DPong) {} 
} 

message DPong { 
    string name = 1; 
} 

サーバー:

import random 
import string 
import threading 

import grpc 

import scenario_pb2_grpc 
import scenario_pb2 
import time 
from concurrent import futures 

class Scenario(scenario_pb2_grpc.ScenarioServicer): 

    def Chat(self, request_iterator, context): 
     def stream(): 
      while 1: 
       time.sleep(1) 
       yield random.choice(string.ascii_letters) 

     output_stream = stream() 

     def read_incoming(): 
      while 1: 
       received = next(request_iterator) 
       print('received: {}'.format(received)) 

     thread = threading.Thread(target=read_incoming) 
     thread.daemon = True 
     thread.start() 

     while 1: 
      yield scenario_pb2.DPong(name=next(output_stream)) 


if __name__ == '__main__': 
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) 
    scenario_pb2.add_ScenarioServicer_to_server(
     Scenario(), server) 

    server.add_insecure_port('[::]:50052') 
    server.start() 
    print('listening ...') 
    while 1: 
     time.sleep(1) 

クライアント

import threading 

import grpc 
import time 

import scenario_pb2_grpc, scenario_pb2 


def run(): 
    channel = grpc.insecure_channel('localhost:50052') 
    stub = scenario_pb2_grpc.ScenarioStub(channel) 
    print('client connected') 

    def stream(): 
     while 1: 
      yield scenario_pb2.DPong(name=input('$ ')) 

    input_stream = stub.Chat(stream()) 

    def read_incoming(): 
     while 1: 
      print('received: {}'.format(next(input_stream).name)) 

    thread = threading.Thread(target=read_incoming) 
    thread.daemon = True 
    thread.start() 

    while 1: 
     time.sleep(1) 

if __name__ == '__main__': 
    print('client starting ...') 
    run() 
+0

余分なスレッドがアプリケーションにどれくらいのコストをかけているかを説明できますか? –

答えて

1

あなたが費やしているスレッドを費やすことなく、これを実行することはできません。我々は、実装が別のスレッドを取らないようにする拡張機能を実装することを考えていますが、それらは数か月先のものです。

+0

GRPCファイルハンドルを選択できるようにすることはできますか? – user2221323

+0

現時点ではありません。ごめんなさい。 –