Django 通道失败:WebSocket 握手期间出错:net::ERR_CONNECTION_RESET

Posted

技术标签:

【中文标题】Django 通道失败:WebSocket 握手期间出错:net::ERR_CONNECTION_RESET【英文标题】:Django Channels failed: Error during WebSocket handshake: net::ERR_CONNECTION_RESET 【发布时间】:2020-01-01 12:30:53 【问题描述】:

我被这个错误困住了,我试图改变很多东西来修复,但仍然出现错误:

(索引):42 WebSocket 连接到“ws://127.0.0.1:8000/ws/chat/user2/”失败:WebSocket 握手期间出错:net::ERR_CONNECTION_RESET

下面是我的代码:

客户端:

var roomName =  room_name_json ;
    var formdata=$("#form");
    var input_val=$("#id_messages");
    var chatHolder=$("#chat-items");
    loc=window.location;  // get the addresses
    console.log(window.location);

    var chatSocket = new WebSocket("ws://" +'127.0.0.1:8000' +
        '/ws/chat/' + roomName + '/');
    console.log(chatSocket);


    // client side receives the message
    chatSocket.onmessage = function(e) 
     console.log("message",e)
    ;

    chatSocket.onclose = function(e) 
        console.error('Chat socket closed unexpectedly');
    ;

    chatSocket.onopen = function(e)
        console.log("open",e);
        formdata.submit(function (event) 
            event.preventDefault();
            var msgText=input_val.val();
            var finalData=
                'message':msgText
            ;
            chatSocket.send(JSON.stringify(finalData));
            formdata[0].reset()
        )
    ;

    chatSocket.onmessage=function(e)
        var chatdata=JSON.parse(e.data);

      chatHolder.append("<li>"+chatdata.message+ " via "+ chatdata.username +"</li>")
    ;


    chatSocket.onerror= function(e)
        console.log("error",e)
    ;

Consumer.py

 def __init__(self, scope):
        super().__init__(scope)
        self.chat_room=""

    async def websocket_connect(self,event):
        me=await self.get_user("user")
        other_user="user2" # let pass static value for now for user 2
        thread_obj=await self.get_thread(me,other_user)
        chat_room=f"thread_thread_obj.id"
        self.chat_room=chat_room
        await self.channel_layer.group_add(
            self.chat_room,
            self.channel_name
        )
        await self.send(
            "type": "websocket.accept"
        )
        print(thread_obj)
        #await asyncio.sleep(10)

    async def websocket_disconnect(self, event):
        print("disconnected",event)

    async def websocket_receive(self, event):
        front_text=event.get('text',None)

        if front_text is not None:
            load_dict_data=json.loads(front_text)
            msg=load_dict_data.get('message')
            user=self.scope['user']
            username="default"

            if user.is_authenticated:
                username=user.username

            myResponse = 
                'message': msg,
                'username': username
            
            # broadcast the message
            await self.channel_layer.group_send(
                self.chat_room,
                
                    "type": "chat_message",
                    "text":json.dumps(myResponse)

                
            )

# message to be sent
    async def chat_message(self,event):
        await self.send(
            "type": "websocket.send",
            "text": event['text']

        )

    @database_sync_to_async
    def get_thread(self,user,other_username):
        return Thread.objects.get_or_new(user,other_username)[0]

    @database_sync_to_async
    def get_user(self,username):
        Muser=User.objects.get(username=username)
        return Muser

Settings.py:

ASGI_APPLICATION = "Frames.routing.application"
CHANNEL_LAYERS=
    "default":
      "BACKEND": "channels_redis.core.RedisChannelLayer",
      "CONFIG": 
                "hosts": [("localhost", 6379)],
            ,
    ,

routing.py

application = ProtocolTypeRouter(
    # (http->django views is added by default)
    'websocket': AuthMiddlewareStack(
        URLRouter(
            chat.routing.websocket_urlpatterns
        )
    ),
)

请求发送的socket url是正确的,但连接总是失败。我该如何解决这个问题,是不是某种redis问题?

【问题讨论】:

为什么你的一些方法在__init__()里面? 【参考方案1】:

我遇到了类似的问题,原来是由于 django 和 redis 之间的连接不好。尝试为通道层使用其他东西。

ASGI_APPLICATION = "Frames.routing.application"

CHANNEL_LAYERS = 
    'default': 
        'BACKEND': 'channels.layers.InMemoryChannelLayer',
    

来源:https://channels.readthedocs.io/en/latest/topics/channel_layers.html?highlight=channels.layers.InMemoryChannelLayer#in-memory-channel-layer

警告:不可用于生产。

如果这能解决问题,您至少会知道您的问题与 redis 连接有关。

(编辑):如果还没有,请尝试将您的 redis 升级到 v5

【讨论】:

【参考方案2】:
CHANNEL_LAYERS = 
'default': 
    'BACKEND': 'channels.layers.InMemoryChannelLayer',
,
'CONFIG': 
        "hosts": [('redis',6379)],
    ,

你应该存储它,它对我有用

【讨论】:

以上是关于Django 通道失败:WebSocket 握手期间出错:net::ERR_CONNECTION_RESET的主要内容,如果未能解决你的问题,请参考以下文章

Django:WebSocket 握手期间出错:意外的响应代码:500

WebSocket 连接失败。 WebSocket握手期间出错-socketjs

websocket失败:WebSocket握手期间出错:意外响应代码:400

Opera 12 中的 WebSocket 握手失败(错误请求)

使用 Maven,WebSocket 连接失败:WebSocket 握手期间出错:意外响应代码:404

WebSocket 连接到“ws://localhost:8080/”失败:WebSocket 握手期间出错:意外响应代码:404