0

I am using channels to implement WebSockets. I am trying to send data through websocket from post_save django signal. Below is my code.

signals.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
            }
        )

consumers.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
        }))

this same piece of code is working on my local machine(windows) but when i am trying to run this code on server(ubuntu 16.04) i am getting bellow error:

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'

also when i am sending data normally from javascript .send() function it is working normally on server but when post_save signal is called then only i get this error on server. this is working fine on my local system. I tried removing async_to_sync from signals then it is not giving error but it is not transmitting data through web socket. then it is giving:

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

I am using pythom 3.5.2 on both local and server.

I don't know whats wrong. is it code or something else. any help is appreciated. Thanks

1 Answer 1

3

Judging by the stack trace, asgiref is accessing the private asyncio function _get_running_loop to obtain functionality equivalent to 3.7's get_running_loop in older Python versions. But you are running 3.5.2 which lacks even the private function.

Try upgrading your Python to 3.6 or 3.7 and things will likely work.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.