Сервер gRPC с графическим интерфейсом Tkinter зависает - PullRequest
0 голосов
/ 29 сентября 2018

Я пытаюсь создать приложение Tkinter, которое будет отвечать на запросы других приложений в качестве сервера gRPC.Графический интерфейс запускается, но простая программа, использующая его, зависает при ожидании ответа.

Графический интерфейс выглядит следующим образом:

import ScrolledText
from Tkinter import BOTH, END, LEFT
from concurrent import futures
import grpc
import output_pb2
import output_pb2_grpc
import threading
from contextlib import contextmanager
import time
class TextWindow():

    def __init__(self, port=51151):
        self.port = port
        print('Starting output window')
        self.stext = ScrolledText.ScrolledText(bg='white', height=10)
        self.stext.pack(fill=BOTH, side=LEFT, expand=True)
        self.stext.focus_set()
        self.output = Output(self)
        self.stext.bind('<Destroy>', self.close, add='+')

        with self.serve():
            print('Listening on test')
            while True:
                self.stext.update()
                self.stext.update_idletasks()
                time.sleep(0.5)

    def append(self, text):
        self.stext.insert(END, text)

    def close(self, event=None):
        self.server.stop(None)

    @contextmanager
    def serve(self):
        self.server = grpc.server(futures.ProcessPoolExecutor(max_workers=10))
        output_pb2_grpc.add_OutputServicer_to_server(self.output, self.server)
        self.server.add_insecure_port('[::]:%d' % self.port)
        self.server.start()
        yield
        self.server.stop(0)

class Output(output_pb2_grpc.OutputServicer):
    """
      Chatbot relay service 
    """

    def __init__(self, window):
        self.window = window

    def Output(self, request, context):
        """Methods to get information from the active engine.
        """
        self.window.append(request.text)
        return output_pb2.Text(message='Got string %s!' % request.text)


if __name__ == "__main__":
    TextWindow()

(Метод serve свободно взят из это сообщение в блоге , я пробовал другие вещи, такие как запуск в новой теме, tkinter mainloop и т. д.) Пример скрипта вызывающей программы выглядит следующим образом:

import grpc
import output_pb2_grpc
import output_pb2

def run(text='Hi!'):
    channel = grpc.insecure_channel('localhost:51151')
    stub = output_pb2_grpc.OutputStub(channel)
    string = output_pb2.Text(text=text)
    #Line that hangs:
    response = stub.Out(string)
    print("Output client received: " + response.text)

if __name__ == '__main__':
    run()

Кажется, что графический интерфейс работает нормально, носкрипт (запускается отдельно после него) нет.Ожидается, что текст Hi появится в графическом интерфейсе, а Got string Hi!! появится в консоли.Но в графическом интерфейсе ничего не появляется и скрипт не заканчивается.Я думаю, что есть некоторая проблема потока, но не знаю, что это.Я использую Python 2.7.Может ли кто-нибудь помочь, пожалуйста?

...