веб-сокет python3 в теме - PullRequest
       5

веб-сокет python3 в теме

0 голосов
/ 30 октября 2019

У меня есть простой Python Tkinter GUI с парой кнопок. Когда я нажимаю кнопку, все, что я хочу сделать, это запустить соединение через веб-сокет и начать получать. Я могу запустить код нормально, но как только я пытаюсь поместить его в поток, я получаю ошибки

RuntimeError: There is no current event loop in thread

Итак, сначала попробуйте:

import websockets
websocket = websockets.connect(uri, ssl = True)
websocket.recv()

Я получаю ошибку

"Connect object has no attribute 'recv'"

Что странно, когда я запускаю его по-другому, я не получаю эту ошибку, когда точно следую документации

   def run_websockets2(self):
        async def hello():
            uri = Websocket_Feed
            # with websockets.connect(uri, ssl=True) as websocket:
            socket = await websockets.connect(uri, ssl=True)
            self.web_socket = socket
            while self.running:
                greeting = await socket.recv()
                print(f"< {greeting}")
        asyncio.get_event_loop().run_until_complete(hello())

Она работает, пока я просто вызываю "websockets2 ()". Но если я пытаюсь сделать

self.websocket_thread = threading.Thread(target=self.run_websockets2, args=())
self.websocket_thread.start()

, я получаю ошибку

RuntimeError: There is no current event loop in thread 'web_sockets'

И когда я делаю всю функцию не асинхронной, я получаю ошибку

def run_websockets(self):
    uri = Websocket_Feed
    # with websockets.connect(uri, ssl=True) as websocket:
    socket = websockets.connect(uri, ssl=True)
    self.web_socket = socket
    while self.running:
        greeting = socket.recv()
        print(f"< {greeting}")

Я получаю ошибку RuntimeError: в потоке 'web_sockets' нет текущего цикла событий. on socket = websockets.connect (uri, ssl = True)

Я не понимаю, почему я не могу просто запустить эти не асинхронные в потоке. Любая помощь с благодарностью

Ответы [ 2 ]

1 голос
/ 30 октября 2019

У вас есть несколько разных ошибок, что немного запутывает картину. Во-первых, относительно:

 "Connect object has no attribute 'recv'"

... это просто говорит о том, что у объекта websocket нет метода с именем recv

Основная проблема, с которой вы пытаетесь вызвать run_websockets2() изпорожденная нить. Т.е. вызов этого метода из основного потока работает, но вызов этого из нового потока не удался.

Это ожидаемое поведение. Это связано с тем, что в порожденном потоке (т. Е. В потоке, отличном от основного потока) не определен цикл событий asyncio. Но для удобства определен в главном потоке. Таким образом, asyncio знает, вызываете ли вы из порожденного потока или основного потока, и ведет себя иначе. Смотрите этот ответ для подробного объяснения. Почему метод asyncio.get_event_loop проверяет, является ли текущий поток основным потоком?

Чтобы решить вашу проблему, вы можете создать новый цикл обработки событий для порожденного потока, чтобы код стал:

event_loop = asyncio.new_event_loop()
event_loop.run_until_complete(hello())

вместо

asyncio.get_event_loop().run_until_complete(hello())

Или вы можете хранить event_loop в обычном месте и разрешить всем порожденным потокам повторно использовать этот цикл событий.

0 голосов
/ 30 октября 2019

Я хотел опубликовать, как я на самом деле решил свой код благодаря @Darren Smith. Я просто добавил одну строку кода «asyncio.set_event_loop (asyncio.new_event_loop ())» в начало.

 def run_websockets2(self):
        asyncio.set_event_loop(asyncio.new_event_loop())

        async def hello():
            uri = Websocket_Feed
            # with websockets.connect(uri, ssl=True) as websocket:
            socket = await websockets.connect(uri, ssl=True)
            self.web_socket = socket
            while self.running:
                greeting = await socket.recv()
                print(f"< {greeting}")

        asyncio.get_event_loop().run_until_complete(hello())

Я должен признать, я люблю python, но иметь код, который в основном работает по-разному в зависимости отпо своему контексту, и исправление - это одна строка, которая не связана с контекстом, кажется, в очень плохом состоянии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...