【问题标题】:Django ChannelsDjango 频道
【发布时间】:2016-08-10 15:03:46
【问题描述】:

我对 Django Channels、WebSockets 和聊天应用程序没有什么疑问。与谷歌一起服务让我进入了聊天室,人们可以在那里建立联系并开始聊天。但我不知道一个用户如何向另一个用户发送即时消息。

例如:

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)

【问题讨论】:

    标签: python django chat django-channels


    【解决方案1】:

    只需为用户对创建“自动唯一房间”。其余的保持不变。比如这样的

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

    给它两个用户对象,它会为这对用户返回一个唯一的房间,订购User.id,对于User.id“1”和“2”的用户,类似于“chat-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 表等。因为在两个用户之间发送消息时,组名总是即时创建的。


    另一件重要的事情:一个用户连接的时间比另一个用户晚,并且可能会错过最初的消息。因此,当您连接时,您可能想要检查一些“chat_messages”数据库表,获取用户对之间的最后 10 或 20 条消息,然后将它们发回。这样用户就可以了解他们过去的对话。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-26
      • 2020-03-31
      • 1970-01-01
      • 2019-02-15
      • 2021-12-22
      • 2017-07-25
      • 2018-08-01
      相关资源
      最近更新 更多