3

我正在使用带有装饰器的Django Channels@channel_session_user(用于访问 Django 的会话数据)。

@channel_session_user_from_http
def ws_connect(message):
    # creates group names like "group-1"
    group_kw = get_group_id_for_user(message.user)
    Group(group_kw).add(message.reply_channel)

@channel_session_user
def ws_receive(message):
    group_kw = get_group_id_for_user(message.user)
    payload = json.loads(message.content['text'])
    Channel(payload['action']).send(message.content)

@channel_session_user
def ws_disconnect(message):
    group_kw = get_group_id_for_user(message.user)
    Group(group_kw).discard(message.reply_channel)

这工作正常,但在测试时出现问题。

下面的测试应该在websocket.receive通道上放置一条消息,然后ws_receive应该获取消息并将其放置在消息action值中定义的通道上。最后,我测试它是否真的放在那个频道上。

def test_send_chat_message_is_used_by_consumer(self):
    # Make sure a user is authenticated
    self.assertTrue(auth.get_user(self.client).is_authenticated())

    payload = {'action': 'chat.receive',
               'msg': 'Test message.',
               'receiver': self.user2.id}
    message = {'text': json.dumps(payload)}

    # Send a chat message
    Channel('websocket.receive').send(message)
    # Receive it and place it on the right channel
    ws_receive(self.get_next_message('websocket.receive', require=True))
    # Fetch it from the channel
    result = self.get_next_message(payload['action'], require=True)
    # That should be the message sent
    self.assertEqual(result, message)

相反,我收到以下错误,指向ws_receive()调用所在的行。

ValueError: No reply_channel 发送给消费者;@channel_session 只能用于包含它的消息。

错误在Channels中引发。

打印reply_channel返回None而不是包含正确的回复通道名称。

tmp = self.get_next_message('websocket.receive', require=True)
print(tmp.reply_channel)  # prints: None

我忽略了一些明显的东西?

4

2 回答 2

1

我认为你不能简单地调用消费者,因为它有装饰器@channel_session_user。您应该尝试使用客户端 channels.tests 提供的。

from channels.tests import ChannelTestCase, Client

然后在测试函数中使用类似这样的东西

client = Client()
client.send('websocket.receive', content=message)
于 2016-10-19T03:59:05.773 回答
0

这是因为您提供给“频道”对象的名称代表了接收此消息的频道。检查Channel的init函数

还要注意tests/base.py 文件中的get_next_message函数。这里的通道参数是指测试期间消息发送到的(回复)通道。

回答你的问题——

查看channels/message.py中 Message 对象的文档字符串。它说,

消息内容是一个名为 .content 的字典,而 reply_channel 是一个可选的额外属性,表示用于回复此消息的最终用户的通道(如果有意义的话)。

您需要在您发送的字典中设置“reply_channel”。

message = {
    'text': json.dumps(payload),
    'reply_channel': 'websocket.receive'
}

希望能帮助到你

于 2016-12-14T13:51:55.867 回答