简体   繁体   中英

Django Channels testing fails

I'm putting up django-channels on a basic django site, configured in the following way.

consumers.py

from channels.generic.websocket import WebsocketConsumer
import json


class ChatConsumer(WebsocketConsumer):
    def connect(self):
        self.accept()

    def disconnect(self, close_code):
        pass

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

        self.send(text_data=json.dumps({
            'message': message
        }))

routing.py

from django.conf.urls import url

from consumers import ChatConsumer

#supposed to be on the main routing
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter

websocket_urlpatterns = [
    url(r'^ws/chat/$', ChatConsumer),
]

#after linking to above as chat.routing
application = ProtocolTypeRouter({
    # (http->django views is added by default)
    'websocket': AuthMiddlewareStack(
        URLRouter(
            websocket_urlpatterns
        )
    ),
})

settings.py

ASGI_APPLICATION = 'chatsys.routing.application'
CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': {
            "hosts": [('35.185.80.98', 6379)],
        },
    },
}

INSTALLED_APPS = [
    ...
    'channels',
]

After installing the necessary applications I went to the next step in the tutorial that's testing this on the shell.

In [1]: import channels.layers

In [2]: from asgiref.sync import async_to_sync

In [3]: async_to_sync(channel_layer.send)('test_channel', {'type': 'hello'})
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-3-80e65666e9e2> in <module>()
----> 1 async_to_sync(channel_layer.send)('test_channel', {'type': 'hello'})

NameError: name 'channel_layer' is not defined

In [4]: channel_layer = channels.layers.get_channel_layer()

In [5]: async_to_sync(channel_layer.send)('test_channel', {'type': 'hello'})
---------------------------------------------------------------------------
TimeoutError                              Traceback (most recent call last)
<ipython-input-5-80e65666e9e2> in <module>()
----> 1 async_to_sync(channel_layer.send)('test_channel', {'type': 'hello'})

~/webapp/chatenv/lib/python3.6/site-packages/asgiref/sync.py in __call__(self, *args, **kwargs)
     62             )
     63         # Wait for results from the future.
---> 64         return call_result.result()
     65 
     66     def __get__(self, parent, objtype):

/usr/lib/python3.6/concurrent/futures/_base.py in result(self, timeout)
    423                 raise CancelledError()
    424             elif self._state == FINISHED:
--> 425                 return self.__get_result()
    426 
    427             self._condition.wait(timeout)

...

    451 
    452     def _sock_connect(self, fut, sock, address):
/usr/lib/python3.6/asyncio/selector_events.py in _sock_connect_cb(self, fut, sock, address)
    478             if err != 0:
    479                 # Jump to any except clause below.
--> 480                 raise OSError(err, 'Connect call failed %s' % (address,))
    481         except (BlockingIOError, InterruptedError):
    482             # socket is still registered, the callback will be retried later
TimeoutError: [Errno 110] Connect call failed ('35.185.80.98', 6379)

It fails to connect and returns a Connection failure. I assumed possibly the issue was that redis was not active so I exited the shell and checked and this was the result.

(chatenv) muiruri_samuel@train:~/webapp/chatsys$ sudo docker run -p 6379:6379 -d redis:2.8
87ee2decc507984ffa153f7b9367a51786bc16ebf6ea330ebb0a030d99b60854
docker: Error response from daemon: driver failed programming external connectivity on endpoint infallible_payne (f40e48395d0e09e2741b1083b548ff2d0843f7ec150294
dbbb72acb3d5f61ea1): Bind for 0.0.0.0:6379 failed: port is already allocated.

so the port is already allocated and it's running.

Found out the issue was setting the IP of the server on settings instead of localhost

CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': {
            "hosts": [('127.0.0.1', 6379)],
        },
    },
}

so replacing it to this worked.

Please check the server port. Is it available to connect from the outside from the server. I mean It's connect from the public internet. I think this is the issue is here.

Run this command in your Linux terminal or Windows cmd to check the port is available to connect from your physical machine network.

telnet 35.185.80.98 6379

use following code:

from channels.layers import get_channel_layer
channel_layer = get_channel_layer()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM