我正在使用 Django频道和@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:没有向消费者发送reply_channel; @channel_session只能用于包含它的邮件。
频道来源中的错误is raised here。
打印reply_channel
返回None
,而不是包含正确的回复频道名称。
tmp = self.get_next_message('websocket.receive', require=True)
print(tmp.reply_channel) # prints: None
我忽略了一些明显的东西?
答案 0 :(得分:1)
我认为你不能只是简单地调用消费者,因为它有装饰器@channel_session_user
。您应该尝试使用客户端channels.tests提供。
from channels.tests import ChannelTestCase, Client
然后在测试函数中使用类似的东西
client = Client()
client.send('websocket.receive', content=message)
答案 1 :(得分:0)
这是因为您提供给'频道' object表示收到此消息的频道。查看频道的init function。
还要注意tests / base.py文件中的函数get_next_message。此处的频道参数指的是在测试期间将消息发送到的(回复)频道。
回答您的问题 -
查看channels / message.py中的docstring of Message object。它说,
消息内容是一个名为.content的字典,而reply_channel是一个可选的额外属性,表示用于回复此消息的最终用户的频道,如果有意义的话。
您需要设置" reply_channel"在你发送的词典中。
message = {
'text': json.dumps(payload),
'reply_channel': 'websocket.receive'
}
希望有所帮助