Django 频道
Django Channels
我对 Django Channels、WebSockets 和聊天应用程序没什么疑问。服务 google 让我进入聊天室,人们可以在那里连接并开始聊天。但是我不知道一个用户如何向另一个用户发送即时消息。
例如:
1) 我将 John 添加为好友,并想开始聊天。
2) 在服务器端,我可以生成对象 Room,我和 John 作为成员。
3) 当我通过 WebSocket 向这个房间发送消息时,我知道这条消息是谁发送的,但我不知道如何获得 John 的频道
@channel_session_user_from_http
def ws_connect(message):
rooms_with_user = Room.objects.filter(members=message.user)
for r in rooms_with_user:
Group('%s' % r.name).add(message.reply_channel)
@channel_session_user
def ws_receive(message):
prefix, label = message['path'].strip('/').split('/')
try:
room = Room.objects.get(name=label)
except Exception, e:
room = Room.objects.create(name=get_random_string(30))
for u in message.chmembers:
room.members.add(u)
# here can be somethis like this
# try
reply_channel = Channels.objects.get(online=True, user=u)
Group('%s' % r.name).add(reply_channel)
Group('%s' % room.name).send({
"text": "%s : %s" % (message.user.username, message['text']),
})
@channel_session_user
def ws_disconnect(message):
prefix, label = message['path'].strip('/').split('/')
Group(label).discard(message.reply_channel)
只需为用户对制作"automatic unique rooms"。其余保持不变。比如像这样
def get_group_name(user1, user2):
return 'chat-{}-{}'.format(*sorted([user1.id, user2.id]))
给它两个用户对象,它 returns 为那对用户提供了一个独特的房间,为 [=12= 的用户订购了 User.id
,类似于 "chat-1-2" ] "1" 和 "2".
这样一来,一个用户可以连接到多个登录设备,并且仍然可以收到两个用户之间发送的消息。
您可以从 message.user
获取经过身份验证的用户的对象。
对于接收用户对象,我只是将 username
与消息一起发送。然后您可以像解压实际消息一样从 message['text']
中解压它。
payload = json.loads(message.content['text'])
msg = payload['msg']
sender = message.user
receiver = get_object_or_404(User, username=payload['receiver'])
# ... here you could check if they have required permission ...
group_name = get_group_name(sender, receiver)
response = {'msg': msg}
Group(group_name).send({'text': json.dumps(response)})
# ... here you could persist the message in a database ...
因此,您可以从示例中删除所有 "room" 内容,包括 room
table 等。因为组名总是在运行时即时创建两个用户之间发送一条消息。
另一件重要的事情:一个用户的连接时间会比另一个用户晚,并且可能会错过初始消息。因此,当您连接时,您可能想要检查一些 "chat_messages" 数据库 table,获取用户对之间的最后 10 或 20 条消息,然后将它们发回。这样用户就可以了解他们过去的对话。
我对 Django Channels、WebSockets 和聊天应用程序没什么疑问。服务 google 让我进入聊天室,人们可以在那里连接并开始聊天。但是我不知道一个用户如何向另一个用户发送即时消息。
例如:
1) 我将 John 添加为好友,并想开始聊天。 2) 在服务器端,我可以生成对象 Room,我和 John 作为成员。 3) 当我通过 WebSocket 向这个房间发送消息时,我知道这条消息是谁发送的,但我不知道如何获得 John 的频道
@channel_session_user_from_http
def ws_connect(message):
rooms_with_user = Room.objects.filter(members=message.user)
for r in rooms_with_user:
Group('%s' % r.name).add(message.reply_channel)
@channel_session_user
def ws_receive(message):
prefix, label = message['path'].strip('/').split('/')
try:
room = Room.objects.get(name=label)
except Exception, e:
room = Room.objects.create(name=get_random_string(30))
for u in message.chmembers:
room.members.add(u)
# here can be somethis like this
# try
reply_channel = Channels.objects.get(online=True, user=u)
Group('%s' % r.name).add(reply_channel)
Group('%s' % room.name).send({
"text": "%s : %s" % (message.user.username, message['text']),
})
@channel_session_user
def ws_disconnect(message):
prefix, label = message['path'].strip('/').split('/')
Group(label).discard(message.reply_channel)
只需为用户对制作"automatic unique rooms"。其余保持不变。比如像这样
def get_group_name(user1, user2):
return 'chat-{}-{}'.format(*sorted([user1.id, user2.id]))
给它两个用户对象,它 returns 为那对用户提供了一个独特的房间,为 [=12= 的用户订购了 User.id
,类似于 "chat-1-2" ] "1" 和 "2".
这样一来,一个用户可以连接到多个登录设备,并且仍然可以收到两个用户之间发送的消息。
您可以从 message.user
获取经过身份验证的用户的对象。
对于接收用户对象,我只是将 username
与消息一起发送。然后您可以像解压实际消息一样从 message['text']
中解压它。
payload = json.loads(message.content['text'])
msg = payload['msg']
sender = message.user
receiver = get_object_or_404(User, username=payload['receiver'])
# ... here you could check if they have required permission ...
group_name = get_group_name(sender, receiver)
response = {'msg': msg}
Group(group_name).send({'text': json.dumps(response)})
# ... here you could persist the message in a database ...
因此,您可以从示例中删除所有 "room" 内容,包括 room
table 等。因为组名总是在运行时即时创建两个用户之间发送一条消息。
另一件重要的事情:一个用户的连接时间会比另一个用户晚,并且可能会错过初始消息。因此,当您连接时,您可能想要检查一些 "chat_messages" 数据库 table,获取用户对之间的最后 10 或 20 条消息,然后将它们发回。这样用户就可以了解他们过去的对话。