我一直在努力为渠道的多元化示例项目中的一位消费者创建一个测试:https://github.com/andrewgodwin/channels-examples/tree/master/multichat。消费者功能如下所示:
@channel_session_user
def chat_join(message):
print(message.content)
room = get_room_or_error(message[MsgFields.ROOM], message.user)
if NOTIFY_USERS_ON_ENTER_OR_LEAVE_ROOMS:
room.send_msg(None, message.user.nickname, message.user.id, MSG_TYPE_ENTER)
room.websocket_group.add(message.reply_channel)
message.channel_session[ChannelSession.ROOMS] = list(set(message.channel_session[ChannelSession.ROOMS]).union([room.id]))
recent_msgs = Message.objects.filter(room=room.id).order_by(ChatModelFields.CREATED_AT)[:10]
history = []
for msg in recent_msgs:
history.append({
ChatModelFields.CONTENT: msg.content,
ChatModelFields.CREATOR: msg.creator,
MsgFields.MSG_TYPE: MSG_TYPE_MESSAGE,
})
message.reply_channel.send({
'text': json.dumps({
MsgFields.USER_JOIN: str(room.id),
'history': history,
})
})
现在,我一直遇到的有趣错误是这样的。 在我的测试功能版本1中:
def test_chat_send(self):
user = HubUser.objects.create_user(
self.TEST_EMAIL,
password=self.TEST_PASSWORD,
nickname=self.TEST_NICKNAME
)
room = ChatRoom.objects.create(creator=self.TEST_NICKNAME)
msg_join = {
MsgFields.ROOM: 1,
MsgFields.COMMAND: 'join',
}
msg_send = {
MsgFields.MESSAGE: self.TEST_MSG,
MsgFields.CREATOR: user,
MsgFields.ROOM: 1,
MsgFields.COMMAND: 'send',
}
c = HttpClient()
c.login(username=self.TEST_EMAIL, password=self.TEST_PASSWORD)
c.send_and_consume(RECEIVER_CHANNEL, content=msg_join, fail_on_none=True)
测试给出了以下错误:
Traceback (most recent call last):
File "J:\Web\HubService\src\chat\tests\tests.py", line 60, in test_chat_send
c.send_and_consume(RECEIVER_CHANNEL, content=msg_join, fail_on_none=True)
File "C:\Users\Doge\Envs\dogeenv\lib\site-packages\channels\tests\base.py", line 127, in send_and_consume
return self.consume(channel, fail_on_none=fail_on_none)
File "C:\Users\Doge\Envs\dogeenv\lib\site-packages\channels\tests\base.py", line 118, in consume
raise AssertionError("Can't find consumer for message %s" % message)
AssertionError: Can't find consumer for message <channels.message.Message object at 0x0000000006086B70>
测试功能版本2:
def test_chat_send(self):
user = HubUser.objects.create_user(
self.TEST_EMAIL,
password=self.TEST_PASSWORD,
nickname=self.TEST_NICKNAME
)
room = ChatRoom.objects.create(creator=self.TEST_NICKNAME)
msg_join = {
MsgFields.ROOM: 1,
MsgFields.COMMAND: 'join',
}
msg_send = {
MsgFields.MESSAGE: self.TEST_MSG,
MsgFields.CREATOR: user,
MsgFields.ROOM: 1,
MsgFields.COMMAND: 'send',
}
c = HttpClient()
c.login(username=self.TEST_EMAIL, password=self.TEST_PASSWORD)
c.send(RECEIVER_CHANNEL, content=msg_join)
c.consume(RECEIVER_CHANNEL, fail_on_none=True)
现在,测试可以成功将消息路由到正确的使用者,但由于用户身份验证而无法继续:
Traceback (most recent call last):
File "J:\Web\HubService\src\chat\tests\tests.py", line 59, in test_chat_send
c.consume(RECEIVER_CHANNEL, fail_on_none=True)
File "C:\Users\Doge\Envs\dogeenv\lib\site-packages\channels\tests\base.py", line 116, in consume
return consumer(message, **kwargs)
File "C:\Users\Doge\Envs\dogeenv\lib\site-packages\channels\sessions.py", line 64, in inner
return func(message, *args, **kwargs)
File "C:\Users\Doge\Envs\dogeenv\lib\site-packages\channels\auth.py", line 42, in inner
return func(message, *args, **kwargs)
File "J:\Web\HubService\src\chat\consumers.py", line 38, in chat_join
room = get_room_or_error(message[MsgFields.ROOM], message.user)
File "J:\Web\HubService\src\chat\utils.py", line 24, in get_room_or_error
raise ClientError("User not logged in")
chat.exceptions.ClientError: User not logged in
我的问题是:
1)为什么调用HttpClient.send
和HttpClient.consume
会分别产生与调用HttpClient.send_and_consume
不同的行为。我查看了send_and_consume函数,它只是像我的方式一样单独调用send和consume。
2)如何使其工作以便我不会收到用户登录错误?
答案 0 :(得分:0)
我实际上在经过一些挖掘之后找到了答案。
1)send_and_consume
与调用send
然后consume
的行为不同,因为我在这里使用HttpClient。 HttpClient继承自Client并拥有自己的send
方法实现,但它没有实现send_and_consume
方法。如果你调用send_and_consume,你实际上是在调用Client.send
和Client.consume
,但就我而言,我需要HttpClient.send
和Client.consume
。
2)为了避免用户登录错误,我必须初始化会话。这可以在另一个消费者中完成。在这个例子中是这样的:
@channel_session_user_from_http
def ws_connect(message):
# Initialise their session
message.channel_session['rooms'] = []
所以这是我把所有部分放在一起后的代码:
def user_connect(self, client):
client.send('websocket.connect', path='/chat/stream')
client.consume('websocket.connect', fail_on_none=True)
def test_chat_join(self):
user = HubUser.objects.create_user(
self.TEST_EMAIL,
password=self.TEST_PASSWORD,
nickname=self.TEST_NICKNAME
)
room = ChatRoom.objects.create(creator=self.TEST_NICKNAME)
c = HttpClient()
c.login(username=self.TEST_EMAIL, password=self.TEST_PASSWORD)
self.user_connect(c)
msg_join = {
MsgFields.ROOM: 1,
MsgFields.COMMAND: 'join',
}
c.send(RECEIVER_CHANNEL, content=msg_join)
c.consume(RECEIVER_CHANNEL, fail_on_none=True)
# asserts and etc...
我希望这可以帮助有类似问题的人。