Python 组和通道层使进程停止而不会引发异常

Python 组和通道层使进程停止而不会引发异常,python,django,redis,django-channels,asgi,Python,Django,Redis,Django Channels,Asgi,从这个非常简单的工作代码示例开始: from channels.generic.websocket import JsonWebsocketConsumer class IsacomptaManagementFeesConsumer(JsonWebsocketConsumer): pass from channels.generic.websocket import JsonWebsocketConsumer class IsacomptaManagementFeesConsume

从这个非常简单的工作代码示例开始:

from channels.generic.websocket import JsonWebsocketConsumer

class IsacomptaManagementFeesConsumer(JsonWebsocketConsumer):
    pass
from channels.generic.websocket import JsonWebsocketConsumer

class IsacomptaManagementFeesConsumer(JsonWebsocketConsumer):

    def connect(self):
        print("one")
        self.accept()
        print("two")
        self.send_json({'text': "Foobar"})
        print("three")
当从javascript连接到此websocket使用者时,这将按预期工作。连接已正确发布,我获得以下日志:

WebSocket HANDSHAKING /manager/accounting/isacompta/2020/03/management-fees.ws [192.168.96.1:38108]
WebSocket CONNECT /manager/accounting/isacompta/2020/03/management-fees.ws [192.168.96.1:38108]
WebSocket DISCONNECT /manager/accounting/isacompta/2020/03/management-fees.ws [192.168.96.1:38108]
现在,如果我将代码更改为以下代码,使用组:

from channels.generic.websocket import JsonWebsocketConsumer

class IsacomptaManagementFeesConsumer(JsonWebsocketConsumer):
    groups = ['foobar']
然后,连接失败。JavaScript控制台告诉我:

Firefox can’t establish a connection to the server at ws://antoine.cocoonr.hq:3001/manager/accounting/isacompta/2020/03/management-fees.ws.
error { target: WebSocket, isTrusted: true, srcElement: WebSocket, currentTarget: WebSocket, eventPhase: 2, bubbles: false, cancelable: false, defaultPrevented: false, composed: false, timeStamp: 7804, … }
服务器日志如下所示:

WebSocket HANDSHAKING /manager/accounting/isacompta/2020/03/management-fees.ws [192.168.96.1:38128]
WebSocket DISCONNECT /manager/accounting/isacompta/2020/03/management-fees.ws [192.168.96.1:38128]
但在服务器端没有引发异常

我也可以在不使用组的情况下获得类似的行为。让我们做一个更大的工作代码示例:

from channels.generic.websocket import JsonWebsocketConsumer

class IsacomptaManagementFeesConsumer(JsonWebsocketConsumer):
    pass
from channels.generic.websocket import JsonWebsocketConsumer

class IsacomptaManagementFeesConsumer(JsonWebsocketConsumer):

    def connect(self):
        print("one")
        self.accept()
        print("two")
        self.send_json({'text': "Foobar"})
        print("three")
此代码工作正常,连接正常,以下是服务器日志:

WebSocket HANDSHAKING /manager/accounting/isacompta/2020/03/management-fees.ws [192.168.96.1:38168]
one
WebSocket CONNECT /manager/accounting/isacompta/2020/03/management-fees.ws [192.168.96.1:38168]
two
three
WebSocket DISCONNECT /manager/accounting/isacompta/2020/03/management-fees.ws [192.168.96.1:38168]
但是如果我对我的代码做以下小改动:

from asgiref.sync import async_to_sync
from channels.generic.websocket import JsonWebsocketConsumer

class IsacomptaManagementFeesConsumer(JsonWebsocketConsumer):

    def connect(self):
        print("one")
        self.accept()
        print("two")
        async_to_sync(self.channel_layer.send)(self.channel_name, {
            'type': 'foobar.send',
            'text': "Foobar",
        })
        print("three")

    def foobar_send(self, event):
        print("AAA")
        self.send_json({'text': event['text'])
        print("BBB")
然后,连接正确发出,但立即关闭,进程停止,没有机会打印“三”,并且也没有执行函数“foobar_send”

WebSocket HANDSHAKING /manager/accounting/isacompta/2020/03/management-fees.ws [192.168.96.1:38224]                                                                                                                                                                             
one                                                                                                                                                                                                                                                                             
WebSocket CONNECT /manager/accounting/isacompta/2020/03/management-fees.ws [192.168.96.1:38224]                                                                                                                                                                                 
two                                                                                                                                                                                                                                                                             
WebSocket DISCONNECT /manager/accounting/isacompta/2020/03/management-fees.ws [192.168.96.1:38224]
我不明白为什么没有打印“三”而也没有提出例外。这意味着异常由
self.channel\u layers.send()
引发,并由
isacompanmanagementfeesconsumer.connect()的调用方静默捕获

写完最后一段后,我决定试一试:

import traceback

from asgiref.sync import async_to_sync
from channels.generic.websocket import JsonWebsocketConsumer

class IsacomptaManagementFeesConsumer(JsonWebsocketConsumer):

    def connect(self):
        print("one")
        self.accept()
        print("two")
        try:
            async_to_sync(self.channel_layer.send)(self.channel_name, {
                'type': 'foobar.send',
                'text': "Foobar",
            })
        except Exception as e:
            print(e)
            traceback.print_stack()
        print("three")

    def foobar_send(self, event):
        print("AAA")
        self.send_json({'text': event['text'])
        print("BBB")
就是这样,有一个隐藏的“未找到文件”错误:

我正在使用Django3.0和通道2.4.0以及通道Redis2.4.2。以下是我的频道设置:

 CHANNEL_LAYERS = {                                                                                                                                                          
     'default': {                                                                                                                                                                                                                                                         
         'BACKEND': 'channels_redis.core.RedisChannelLayer',                                                                                                                                                                                                                
         'CONFIG': {                                                                                                                                                                                                                                                       
             'hosts': [                                                                                                                                                                                                                                            
                 {                                                                                                                                                                                                                                                 
                     'address': get_env('CHANNELS_REDIS_HOST',                                                                                                                                                                                          
                                        default='localhost:6379'),                                                                                                                                                                             
                     'password': get_env('CHANNELS_REDIS_PASSWORD',                                                                                                                                                                             
                                         default=None),                                                                                                                                                                                          
                     'db': 1,            
                 },                                                                                                                                  
             ],                                                                                                                                   
         },                                                                                                                                                        
     },                                                                                                                                                        
 }                                                                                                                                                                                                                                                                        

错误被隐藏的事实已由解决


从FileNotFoundError本身开始,它是由错误的
地址
值引起的。它应该作为
传递redis://localhost:6379/“
,而不是
”localhost:6379“

已解决隐藏错误的事实


从FileNotFoundError本身开始,它是由错误的
地址
值引起的。它应该作为
传递redis://localhost:6379/“
,而不是
”localhost:6379“

鉴于我上次的调查,我认为这可能是一个错误,因此提出了一个错误:鉴于我上次的调查,我认为这可能是一个错误,因此提出了一个错误: