AttributeError: модуль 'asyncio' не имеет атрибута '_get_running_loop' - PullRequest
0 голосов
/ 07 июля 2019

Я использую channels для реализации WebSockets.Я пытаюсь отправить данные через websocket из сигнала post_save django.Ниже мой код.

signal.py

@receiver(post_save, sender=CheckIn)
def send_data_on_save(sender, instance, **kwargs):
    channel_layer = get_channel_layer()
    stats = get_stats()
    async_to_sync(channel_layer.group_send)(
            'dashboard',
            {
                'type': 'send_data',
                'message': stats
            }
        )

    analytics = get_analytics()
    async_to_sync(channel_layer.group_send)(
            'analytic',
            {
                'type': 'send_data',
                'message': analytics
            }
        )

consumer.py

class DashboardConsumer(WebsocketConsumer):
    def connect(self):
        self.room_group_name = 'dashboard'

        # Join room group
        async_to_sync(self.channel_layer.group_add)(
            self.room_group_name,
            self.channel_name
        )

        self.accept()

    def disconnect(self, close_code):
        # Leave room group
        async_to_sync(self.channel_layer.group_discard)(
            self.room_group_name,
            self.channel_name
        )

    # Receive message from WebSocket
    def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']

        # Send message to room group
        async_to_sync(self.channel_layer.group_send)(
            self.room_group_name,
            {
                'type': 'send_data',
                'message': message
            }
        )

    # Receive message from room group
    def send_data(self, event):
        message = event['message']

        # Send message to WebSocket
        self.send(text_data=json.dumps({
            'message': message
        }))

этот же кусоккода работает на моей локальной машине (Windows), но когда я пытаюсь запустить этот код на сервере (Ubuntu 16.04), я получаю сообщение об ошибке:

Traceback

Exception inside application: module 'asyncio' has no attribute '_get_running_loop'
    File "/usr/lib/python3.5/asyncio/tasks.py", line 241, in _step
        result = coro.throw(exc)
    File "/home/user1/demowebapps/env/lib/python3.5/site-packages/channels/sessions.py", line 183, in __call__
        return await self.inner(receive, self.send)
    File "/home/user1/demowebapps/env/lib/python3.5/site-packages/channels/middleware.py", line 41, in coroutine_call
        await inner_instance(receive, send)
    File "/home/user1/demowebapps/env/lib/python3.5/site-packages/channels/consumer.py", line 59, in __call__
        [receive, self.channel_receive], self.dispatch
    File "/home/user1/demowebapps/env/lib/python3.5/site-packages/channels/utils.py", line 52, in await_many_dispatch
        await dispatch(result)
    File "/home/user1/demowebapps/env/lib/python3.5/site-packages/asgiref/sync.py", line 145, in __call__
        return await asyncio.wait_for(future, timeout=None)
    File "/usr/lib/python3.5/asyncio/tasks.py", line 373, in wait_for
        return (yield from fut)
    File "/usr/lib/python3.5/asyncio/futures.py", line 361, in __iter__
        yield self  # This tells Task to wait for completion.
    File "/usr/lib/python3.5/asyncio/tasks.py", line 296, in _wakeup
        future.result()
    File "/usr/lib/python3.5/asyncio/futures.py", line 274, in result
        raise self._exception
    File "/usr/lib/python3.5/concurrent/futures/thread.py", line 55, in run
        result = self.fn(*self.args, **self.kwargs)
    File "/home/user1/demowebapps/env/lib/python3.5/site-packages/channels/db.py", line 14, in thread_handler
        return super().thread_handler(loop, *args, **kwargs)
    File "/home/user1/demowebapps/env/lib/python3.5/site-packages/asgiref/sync.py", line 164, in thread_handler
        return func(*args, **kwargs)
    File "/home/user1/demowebapps/env/lib/python3.5/site-packages/channels/consumer.py", line 105, in dispatch
        handler(message)
    File "/home/user1/demowebapps/env/lib/python3.5/site-packages/channels/generic/websocket.py", line 39, in websocket_connect
        self.connect()
    File "/home/user1/demowebapps/vmsbackend/check_in/consumers.py", line 57, in connect
        self.channel_name
    File "/home/user1/demowebapps/env/lib/python3.5/site-packages/asgiref/sync.py", line 41, in __call__
        if asyncio._get_running_loop() is not None:
    module 'asyncio' has no attribute '_get_running_loop'

также, когда я отправляю данные нормально из функции javascript .send(), она нормально работает на сервере, но когда вызывается сигнал post_save, только эта ошибка появляется на сервере.это работает нормально в моей локальной системе.Я попытался удалить async_to_sync из сигналов, тогда он не выдает ошибку, но не передает данные через веб-сокет.тогда это дает:

./check_in/signals.py:47: RuntimeWarning: Coroutine'RedisChannelLayer.group_send' was never awaited
'message': analytics

Я использую Pythom 3.5.2 как на локальном, так и на сервере.

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

1 Ответ

1 голос
/ 08 июля 2019

Судя по трассировке стека, asgiref обращается к закрытой функции asyncio _get_running_loop, чтобы получить функциональность, эквивалентную 3,7 get_running_loop в более старых версиях Python.Но вы используете 3.5.2, в которой отсутствует даже частная функция.

Попробуйте обновить Python до 3.6 или 3.7, и все будет работать.

...