是什么导致我的消费者收到 2 个参数——除了 "message" 之外还有一个?

What is causing my consumer to be sent 2 arguments--one, in addition to the "message"?

我正在执行 multichat 示例,但无法找出导致此错误的原因。这是完整的回溯:

2018-01-05 07:35:48,017 - ERROR - worker - Error processing message with consumer chat.consumers.chat_join:
Traceback (most recent call last):
  File "/Users/sng/.virtualenvs/blog-api/lib/python2.7/site-packages/channels/worker.py", line 119, in run
    consumer(message, **kwargs)
  File "/Users/sng/.virtualenvs/blog-api/lib/python2.7/site-packages/channels/sessions.py", line 78, in inner
    return func(*args, **kwargs)
  File "/Users/sng/.virtualenvs/blog-api/lib/python2.7/site-packages/channels/auth.py", line 42, in inner
    return func(message, *args, **kwargs)
  File "/Users/sng/Dev/django/blog-api/src/chat/utils.py", line 14, in inner
    return func(message, args, **kwargs)
TypeError: chat_join() takes exactly 1 argument (2 given)

我相信我已经几乎按原样复制了代码,所以我不知道它是怎么出错的。

这是消费者:

@channel_session_user
@catch_client_error
def chat_join(message):
    room = get_room_or_error(message["room"], message.user)    
    if NOTIFY_USERS_ON_ENTER_OR_LEAVE_ROOMS:
        room.send_message(None, message.user, MSG_TYPE_ENTER)

    room.websocket_group.add(message.reply_channel)
    message.channel_session['rooms'] = list(set(message.channel_session['rooms']).union([room.id]))

    message.reply_channel.send({
        "text": json.dumps({
            "join": str(room.id),
            "title": room.title,
        }),
    })  

路由:

custom_routing = [
    route("chat.receive", chat_join, command="^join$"),
    route("chat.receive", chat_leave, command="^leave$"),
    route("chat.receive", chat_send, command="^send$"),
]

在常规的 Django 中,我认为并行的是 URLconf 向视图发送了太多的参数。我不确定 message 是从哪里发送的,因此不确定是否有其他任何东西与它一起发送。回溯暗示它是与会话相关的。不太确定在哪里或如何在该域中进行调试。

编辑:我忘了注意:这不会发生在 runserver 上,它会在我尝试进入聊天室时发生。这是相关代码:

{% extends "base.html" %}
{% load staticfiles %}

{% block head_title %}MultiChat Example{% endblock %}
{% block header_text %}MultiChat Example{% endblock %}
{% block content %}

<ul class="rooms">
    {% for room in rooms %}
        <li class="room-link" data-room-id="{{ room.id }}">{{ room.id }}</li>
    {% empty %}
        <p class="empty">No chat rooms defined. Maybe make some in the <a href="{% url 'admin:index' %}">admin</a>?</p>
    {% endfor %}
 </ul>

<div id="chats">
</div>

{% endblock %}

所以当我点击其中一个房间时,会弹出错误并拒绝打开。

JS 文件:

$(function () {
    // Correctly decide between ws:// and wss://
    var ws_scheme = window.location.protocol == "https:" ? "wss" : "ws";
    var ws_path = ws_scheme + '://' + window.location.host + "/chat/stream/";
    console.log("Connecting to " + ws_path);
    var socket = new ReconnectingWebSocket(ws_path);

    // Helpful debugging
    socket.onopen = function () {
        console.log("Connected to chat socket");
    };
    socket.onclose = function () {
        console.log("Disconnected from chat socket");
    };

    socket.onmessage = function (message) {
        // Decode the JSON
        console.log("Got websocket message " + message.data);
        var data = JSON.parse(message.data);
        // Handle errors
        if (data.error) {
            alert(data.error);
            return;
        }
        // Handle joining
        if (data.join) {
            console.log("Joining room " + data.join);
            var roomdiv = $(
                "<div class='room' id='room-" + data.join + "'>" +
                "<h2>" + data.title + "</h2>" +
                "<div class='messages'></div>" +
                "<input><button>Send</button>" +
                "</div>"
            );
            $("#chats").append(roomdiv);
            roomdiv.find("button").on("click", function () {
                socket.send(JSON.stringify({
                    "command": "send",
                    "room": data.join,
                    "message": roomdiv.find("input").val()
                }));
                roomdiv.find("input").val("");
            });
            // Handle leaving
        } else if (data.leave) {
            console.log("Leaving room " + data.leave);
            $("#room-" + data.leave).remove();
        } else if (data.message || data.msg_type != 0) {
            var msgdiv = $("#room-" + data.room + " .messages");
            var ok_msg = "";
            // msg types are defined in chat/settings.py
            // Only for demo purposes is hardcoded, in production scenarios, consider call a service.
            switch (data.msg_type) {
                case 0:
                    // Message
                    ok_msg = "<div class='message'>" +
                        "<span class='username'>" + data.username + "</span>" +
                        "<span class='body'>" + data.message + "</span>" +
                        "</div>";
                    break;
                case 1:
                    // Warning/Advice messages
                    ok_msg = "<div class='contextual-message text-warning'>" + data.message + "</div>";
                    break;
                case 2:
                    // Alert/Danger messages
                    ok_msg = "<div class='contextual-message text-danger'>" + data.message + "</div>";
                    break;
                case 3:
                    // "Muted" messages
                    ok_msg = "<div class='contextual-message text-muted'>" + data.message + "</div>";
                    break;
                case 4:
                    // User joined room
                    ok_msg = "<div class='contextual-message text-muted'>" + data.username + " joined the room!" + "</div>";
                    break;
                case 5:
                    // User left room
                    ok_msg = "<div class='contextual-message text-muted'>" + data.username + " left the room!" + "</div>";
                    break;
                default:
                    console.log("Unsupported message type!");
                    return;
            }
            msgdiv.append(ok_msg);
            msgdiv.scrollTop(msgdiv.prop("scrollHeight"));
        } else {
            console.log("Cannot handle message!");
        }
    };

    // Says if we joined a room or not by if there's a div for it
    function inRoom(roomId) {
        return $("#room-" + roomId).length > 0;
    };

    // Room join/leave
    $("li.room-link").click(function () {
        roomId = $(this).attr("data-room-id");
        if (inRoom(roomId)) {
            // Leave room
            $(this).removeClass("joined");
            socket.send(JSON.stringify({
                "command": "leave",  // determines which handler will be used (see chat/routing.py)
                "room": roomId
            }));
        } else {
            // Join room
            $(this).addClass("joined");
            socket.send(JSON.stringify({
                "command": "join",
                "room": roomId
            }));
        }
    });
});

看起来你的装饰器代码中有一个拼写错误,你没有显示 - 回溯说 chat/utils.py 第 14 行有

return func(message, args, **kwargs)

什么时候应该

return func(message, *args, **kwargs)

大概第二个参数是一个空元组。