2016-08-10 23 views
5

Mam małe pytanie dotyczące kanałów Django, WebSockets i aplikacji do czatu. Udostępniając google, przenosi mnie do czatów, gdzie ludzie mogą się połączyć i rozpocząć czat. Ale nie wiem, w jaki sposób jeden użytkownik może wysłać wiadomość błyskawiczną innego użytkownika.Django Channels

Na przykład:

1) dodam Jana do znajomych i chcesz rozpocząć czat. 2) Po stronie serwera mogę wygenerować obiekt Pokój, ze mną i Johnem jako członkami. 3) Kiedy wysłać wiadomość poprzez websocket do tego pokoju, wiem, dla kogo ta wiadomość jest, ale nie wiem jak dostać Jana kanał

@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) 

Odpowiedz

6

Wystarczy zrobić „automatycznych wyjątkowe pokoje” dla użytkownika pary. Reszta pozostaje taka sama. Na przykład jak ten

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

daję to dwa obiekty użytkowników i zwraca unikalne miejsce dla tej pary użytkowników, nakazał User.id, coś jak „chat-1-2” dla użytkowników z User.id „1” i "2".

W ten sposób użytkownik może łączyć się z więcej niż jednym zalogowanym urządzeniem i nadal otrzymywać wiadomości wysyłane między dwoma użytkownikami.

Możesz uzyskać obiekt użytkownika uwierzytelnionego od message.user.

Dla odbierającego obiektu użytkownika, właśnie wysłałem username wraz z wiadomością. Następnie możesz rozpakować go z urządzenia message['text'] w ten sam sposób, w jaki rozpakowujesz wiadomość.

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 ... 

Więc z tym, można upuścić wszystkie „Pokój” rzeczy ze swoim przykładzie, w tym tabeli room itd. Ponieważ nazwy grupy są zawsze tworzone on-the-fly, gdy wiadomość jest wysłać między dwoma użytkownikami.


Kolejna ważna sprawa: jeden użytkownik połączy się później niż inny użytkownik i może pominąć początkowe wiadomości. Więc kiedy się połączysz, prawdopodobnie chcesz sprawdzić tabelę bazy danych "chat_messages", pobrać ostatnie 10 lub 20 wiadomości między parą użytkowników i odesłać je. Dzięki temu użytkownicy mogą nadrobić zaległe rozmowy.