Skip to main content
 首页 » 编程设计

python之Django channel 测试失败

2025年05月04日24dudu

我在一个基本的 django 站点上放置了 django-channels,配置如下。

消费者.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 
        })) 

路由.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 
        ) 
    ), 
}) 

设置.py

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

安装必要的应用程序后,我进入了 tutorial 中的下一步那是在 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) 

它连接失败并返回连接失败。 我假设问题可能是 redis 未处于事件状态,所以我退出了 shell 并进行了检查,这就是结果。

(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. 

因此端口已经分配并且正在运行。

请您参考如下方法:

发现问题是在设置而不是本地主机上设置服务器的 IP

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

所以将其替换为这个有效。