简体   繁体   English

Django频道

[英]Django Channels

I've little question about Django Channels, WebSockets, and chat applications. 我对Django频道,WebSockets和聊天应用程序一无所知。 Serving with google gets me to chatrooms, where people can connect and start a chat. 与谷歌一起服务让我去聊天室,在那里人们可以连接并开始聊天。 But I don't know how one user can send another user instant message. 但我不知道一个用户如何发送另一个用户即时消息。

For example: 例如:

1) I add John to friends, and want to start chat. 1)我将John添加到朋友,并希望开始聊天。 2) On server side I can generate object Room, with me and John as members. 2)在服务器端,我可以生成对象Room,我和John作为成员。 3) When I send message via WebSocket to this room, I know for who this message is, but I don't know how to get John's channel 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)

Simply make "automatic unique rooms" for user pairs. 只需为用户对设置“自动独特房间”。 The rest stays the same. 其余的保持不变。 For example like this 比如这样

def get_group_name(user1, user2):
    return 'chat-{}-{}'.format(*sorted([user1.id, user2.id]))

Give it two user objects, and it returns a unique room for that pair of users, ordered the User.id , something like "chat-1-2" for the users with User.id "1" and "2". 给它两个用户对象,它为这对用户返回一个唯一的空间,为User.id订购User.id ,比如“chat-1-2”,用户为User.id “1”和“2”。

That way, a user can connect with more than one logged-in device and still get the messages sent between the two users. 这样,用户可以连接多个登录设备,并仍然可以获得两个用户之间发送的消息。

You can get the authenticated user's object from message.user . 您可以从message.user获取经过身份验证的用户对象。

For the receiving User object, I'd just sent the username along with the message. 对于接收用户对象,我只是发送了username和消息。 Then you can unpack it from the message['text'] the same way you unpack the actual message. 然后你可以像解压实际消息一样从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 ...

So with that, you can drop all the "room" things from your example, including the room table etc. Because group names are always created on-the-fly when a message is send between two users. 因此,您可以从示例中删除所有“房间”内容,包括room表等。因为在两个用户之间发送消息时,总是会立即创建组名。


Another important thing: One user will connect later than the other user, and may miss initial messages. 另一个重要的事情:一个用户将比其他用户晚连接,并可能错过初始消息。 So when you connect, you probably want to check some "chat_messages" database table, fetch the last 10 or 20 messages between the user pair, and send those back. 因此,当您连接时,您可能想要检查一些“chat_messages”数据库表,获取用户对之间的最后10或20条消息,然后将其发回。 So users can catch up on their past conversation. 因此,用户可以赶上他们过去的谈话。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM