Django-Channels 中的类型错误

Posted

技术标签:

【中文标题】Django-Channels 中的类型错误【英文标题】:Typeerror in Django-Channels 【发布时间】:2021-01-14 23:26:18 【问题描述】:

我正在尝试在我的 django 应用程序中从客户端发送数据,但我不断收到此错误并且套接字断开连接。我不知道为什么会这样,这是错误:

Exception inside application: receive() got an unexpected keyword argument 'text_data'
Traceback (most recent call last):
  File "/Users/MichaelAjanaku/Desktop/Kitchen-Order/order/lib/python3.6/site-packages/channels/staticfiles.py", line 44, in __call__
    return await self.application(scope, receive, send)
  File "/Users/MichaelAjanaku/Desktop/Kitchen-Order/order/lib/python3.6/site-packages/channels/routing.py", line 71, in __call__
    return await application(scope, receive, send)
  File "/Users/MichaelAjanaku/Desktop/Kitchen-Order/order/lib/python3.6/site-packages/channels/sessions.py", line 47, in __call__
    return await self.inner(dict(scope, cookies=cookies), receive, send)
  File "/Users/MichaelAjanaku/Desktop/Kitchen-Order/order/lib/python3.6/site-packages/channels/sessions.py", line 254, in __call__
    return await self.inner(wrapper.scope, receive, wrapper.send)
  File "/Users/MichaelAjanaku/Desktop/Kitchen-Order/order/lib/python3.6/site-packages/channels/auth.py", line 181, in __call__
    return await super().__call__(scope, receive, send)
  File "/Users/MichaelAjanaku/Desktop/Kitchen-Order/order/lib/python3.6/site-packages/channels/middleware.py", line 26, in __call__
    return await self.inner(scope, receive, send)
  File "/Users/MichaelAjanaku/Desktop/Kitchen-Order/order/lib/python3.6/site-packages/channels/routing.py", line 160, in __call__
    send,
  File "/Users/MichaelAjanaku/Desktop/Kitchen-Order/order/lib/python3.6/site-packages/channels/consumer.py", line 94, in app
    return await consumer(scope, receive, send)
  File "/Users/MichaelAjanaku/Desktop/Kitchen-Order/order/lib/python3.6/site-packages/channels/consumer.py", line 59, in __call__
    [receive, self.channel_receive], self.dispatch
  File "/Users/MichaelAjanaku/Desktop/Kitchen-Order/order/lib/python3.6/site-packages/channels/utils.py", line 51, in await_many_dispatch
    await dispatch(result)
  File "/Users/MichaelAjanaku/Desktop/Kitchen-Order/order/lib/python3.6/site-packages/channels/consumer.py", line 73, in dispatch
    await handler(message)
  File "/Users/MichaelAjanaku/Desktop/Kitchen-Order/order/lib/python3.6/site-packages/channels/generic/websocket.py", line 196, in websocket_receive
    await self.receive(text_data=message["text"])
TypeError: receive() got an unexpected keyword argument 'text_data'
WebSocket DISCONNECT /ws/orders/ [127.0.0.1:49984]

这是消费者.py:

import json
from .models import Order
from channels.db import database_sync_to_async
from channels.generic.websocket import AsyncWebsocketConsumer

class WSConsumer(AsyncWebsocketConsumer):
    
    @database_sync_to_async
    def _get_order_info(self, number):
        order = Order.objects.get(order_number = number)
        return order

  
    async def connect(self):
        self.groupname = 'kitchen'
        await self.channel_layer.group_add(
                    self.groupname,
                    self.channel_name,
                )      
        await self.accept()

   
    async def disconnect(self, code):
        await self.channel_layer.group_discard(
            self.groupname,
            self.channel_name,
        )
        await super().disconnect(code)



    async def take_order(self, event):
        number = event['number']
        details = event['details']
        info = await self._get_order_info(number)
        time_taken = info.order_date_time
        taken_by = info.taken_by
        fulfilled = info.is_fulfilled
        fulfilled_by = info.fulfilled_by

        await self.send(order_data=json.dumps(   
    
                'number' : number,
                'details' : details,
                'time_taken' : time_taken,
                'taken_by' : taken_by,
                'fulfilled' : fulfilled,
                'fulfilled_by' : fulfilled_by,        ))

    async def receive(self, order_data):
        order_data_json = json.loads(order_data)
        number = order_data_json['number']
        details = order_data_json['details']
        time_taken = order_data_json['time_taken']
        taken_by = order_data_json['taken_by']
        fulfilled = order_data_json['fulfilled']
        fulfilled_by = order_data_json['fulfilled_by']

        await self.channel_layer.group_send(
            self.groupname,
               
                'type': 'take_order',
                'number' : number,
                'details' : details,
                'time_taken' : time_taken,
                'taken_by' : taken_by,
                'fulfilled' : fulfilled,
                'fulfilled_by' : fulfilled_by,   
            
        )

这是模板中的 javascript 代码:

var ws_url = 'ws://' + window.location.host + '/ws/orders/';
    var orderSocket = new WebSocket(ws_url);
    document.querySelector('#submit').onclick = function(e) 
        const numberInputDom = document.querySelector('#id_order_number');
        const detailsInputDom = document.querySelector('#id_order_details');
        const number = numberInputDom.value;
        const details = detailsInputDom.value;
        orderSocket.send(JSON.stringify(
            'number': number,
            'details' : details,
        ));
        console.log('data sent')
       
    ; 

我收到该特定错误的任何原因?我整天都在和它作斗争。

【问题讨论】:

async def receive(self, order_data):改成async def receive(self, text_data):? 【参考方案1】:

这是因为该函数是使用关键字参数text_data 调用的,您将其命名为order_data

您需要重命名参数才能使其正常工作。

async def receive(self, text_data):
    order_data_json = json.loads(text_data)
    # Rest of the code ...

【讨论】:

以上是关于Django-Channels 中的类型错误的主要内容,如果未能解决你的问题,请参考以下文章

django-channels / websockets:WebSocketBadStatusException:握手状态200

无法使用 django-channels 连接到 websocket,docker 上的 nginx 作为服务

Django-channels:AttributeError:'str'对象没有属性'profile'

django-channels/websockets: WebSocketBadStatusException: 握手状态 200

在真实服务器中部署 django-channels 的最佳方式

在负载均衡器后面运行多个 daphne 实例:django-channels