[TIL_Carrotww] 66 - 22/12/06

μœ ν˜•μ„Β·2022λ…„ 12μ›” 6일
0

TIL

λͺ©λ‘ 보기
78/138
post-thumbnail

πŸ“Carrotww의 μ½”λ”© 기둝μž₯

🧲 Daphne Channels

πŸ” Channelsλ₯Ό μ΄μš©ν•˜μ—¬ μ‚¬μš©μž μΌλŒ€μΌ μ±„νŒ… κΈ°λŠ₯을 κ΅¬ν˜„ν•˜μ˜€λŠ”λ° 말도 μ•ˆλ˜λŠ” 였λ₯˜μ—μ„œ μ‹œκ°„μ„ λ„ˆλ¬΄ 많이 써 ν˜Ήμ‹œ λͺ°λΌ 끄적여 λ³Έλ‹€. μΌλŒ€μΌ μ±„νŒ…μ˜ κΈ°λŠ₯을 λͺ¨λ‘ κ΅¬ν˜„ν•œ ν›„ μ„œλ‘œ 방을 λ§Œλ“€κ³  채널 λ ˆμ΄μ–΄μ—μ„œ μ±„νŒ… μ „μ†‘κΉŒμ§€ ν…ŒμŠ€νŠΈλ₯Ό ν™•μΈν•˜μ˜€μœΌλ‚˜ DB μ €μž₯ λ‘œμ§μ„ μΆ”κ°€ ν•˜μ˜€μ„λ•Œ 자꾸 λ¦¬λ‘œλ“œ λ˜μ–΄ μ—°κ²°λœ websocket이 ν•΄μ œλ˜λŠ” ν˜„μƒμ΄ μžˆμ—ˆλ‹€.

daphne둜 μ„œλ²„λ₯Ό λŒλ €λ³΄κΈ°λ„ ν•˜κ³  μ—¬λŸ¬ λ°©λ²•μœΌλ‘œ μˆ˜ν–‰ν•˜μ˜€λŠ”λ° ν•˜λ£¨μ’…μΌ κ³ μƒν•œ 것 치고 쑰금 μ–΄μ΄μ—†λŠ” 곳이 λ¬Έμ œμ˜€λ‹€.

vscode ν•œ ν΄λ”μ—μ„œ 같이 μ—΄κ³  front ν…ŒμŠ€νŠΈλŠ” live serverλ₯Ό django serverλŠ” runserver둜 ν…ŒμŠ€νŠΈ ν•˜μ˜€λŠ”λ° λ‹€λ₯Έ vscodeμ—μ„œ liveserverλ₯Ό μ—΄κ³  ν…ŒμŠ€νŠΈλ₯Ό μ§„ν–‰ν•˜μ˜€μ„λ•ŒλŠ” 잘 λ˜λŠ” κ²ƒμ΄μ˜€λ‹€.

μœ„ 였λ₯˜μ˜ 이유인 μ¦‰μŠ¨ ν•œ vscodeμ—μ„œ db μ €μž₯ λ‘œμ§μ„ μΆ”κ°€ ν›„ ν…ŒμŠ€νŠΈ ν•˜κ²Œ 되면 dbκ°€ μ €μž₯, κ°±μ‹ λ˜λ©° 파일의 μ €μž₯이 이루어지고 vscodeκ°€ μƒˆλ‘œκ³ μΉ¨λ˜μ–΄ liveserver도 μƒˆλ‘œκ³ μΉ¨κ³Ό λ™μ‹œμ— μ†ŒμΌ“μ—°κ²°μ΄ 끊기게 λ˜λŠ” κ²ƒμ΄μ˜€λ‹€..
이걸 ν•˜λ£¨λ™μ•ˆ μ°Ύμ•˜λŠ”λ° μ—­μ‹œ λ‹¨μˆœν•œκ³³μ— λ¬Έμ œκ°€ μžˆμ—ˆλ‹€ γ… γ… γ…  μ–΄μ΄μ—†λŠ” 였λ₯˜..? μ˜€λŠ”λ° 무튼 μ΄μ œλŠ” 잘 λœλ‹€.

class CreateRoom(AsyncWebsocketConsumer):
    # django channels authentication 둜그인 κ΄€λ ¨ν•œ 인증 κΈ°λŠ₯ μΆ”κ°€ν•΄μ•Ό 함
    async def connect(self):
        # get room_id value
        self.room_name = self.scope["url_route"]["kwargs"]["room_id"]
        self.room_group_name = "chat_%s" % self.room_name

        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )

        await self.accept()

    async def disconnect(self, close_code):
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )

    async def receive(self, text_data):
        text_data_json = json.loads(text_data)
        room_id = text_data_json['room_id']
        message = text_data_json['message']
        # ν”„λ‘ νŠΈμ—μ„œ sender_id, receiver_id λ³΄λ‚΄μ£ΌλŠ” 둜직 ν•„μš”
        sender_id = text_data_json['sender_id']
        receiver_id = text_data_json['receiver_id']

        sender = await self.get_user_db(sender_id)
        receiver = await self.get_user_db(receiver_id)
        room_object = await self.get_chatroom_db(room_id)

        if not sender:
            print('Sender userκ°€ μ‘°νšŒλ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.')
        if not receiver:
            print('Receiver userκ°€ μ‘°νšŒλ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.')
        if not message:
            print('messageκ°€ μ—†μŠ΅λ‹ˆλ‹€.')
            return

        await self.create_chat_log(room_object, sender, message)

        cur_datetime = datetime.now()
        ampm = cur_datetime.strftime('%p')

        cur_time = datetime.now().strftime('%I:%M')            
        date = datetime.now().strftime('%Yλ…„ %mμ›” %d일')
        cur_time = f"AM {cur_time}" if ampm == 'AM' else f"PM {cur_time}"

        response_json = {
            'message': message,
            'sender': sender.id,
            'room_id': room_id,
            'cur_time': cur_time,
            'date': date
            }

        await self.channel_layer.group_send(
            self.room_group_name,
            {
                'type': 'chat_message',
                'message': json.dumps(response_json)
            }
        )

    # Receive message from room group
    async def chat_message(self, event):
        message_data = json.loads(event['message'])
        message = message_data['message']
        sender = message_data['sender']
        cur_time = message_data['cur_time']
        date = message_data['date']
        room_id = message_data['room_id']

        # Send message to WebSocket
        await self.send(text_data=json.dumps({
            "message": message,
            "sender": sender,
            "cur_time": cur_time,
            "date": date,
            "room_id": room_id
            }))

    @database_sync_to_async
    def get_user_db(self, user_id):
        user = User.objects.filter(id=user_id)
        if user:
            return user[0]
        return None

    @database_sync_to_async
    def get_chatroom_db(self, room_id):
        room = ChatRoom.objects.filter(id=room_id)
        if room:
            return room[0]
        return None

    @database_sync_to_async
    def create_chat_log(self, room_object, sender, content):
        RoomMessage.objects.create(room=room_object, user=sender, content=content)

μ½”λ“œλŠ” 직관적이고 ν•΄λ‹Ή ν•¨μˆ˜λ“€μ€ channels λ‚΄λΆ€ ν•¨μˆ˜λ‘œ room idλ₯Ό λ°›μ•„ group을 μƒμ„±ν•˜κ³  ν•΄λ‹Ή 그룹에 채널 λ ˆμ΄μ–΄λ₯Ό λ§Œλ“ λ‹€.
ν•΄λ‹Ή 채널 λ ˆμ΄μ–΄λ‘œ 메세지λ₯Ό μ „μ†‘ν•˜λ©° 전솑함과 λ™μ‹œμ— db에 메세지가 μ €μž₯이 λ˜λŠ” 것이닀.

🧲 django orm chain

πŸ” chatroom λͺ¨λΈμ— μ†‘μ‹ μž μˆ˜μ‹ μž μˆœμ„œ 상관없이 λ¨Όμ € λ³΄λ‚΄λŠ” μ‚¬λžŒμ΄ μ†‘μ‹ μžκ°€ λ˜μ–΄ μ±„νŒ… 방이 λ§Œλ“€μ–΄ 진닀.
즉 μ–΄λ–€ μ‚¬μš©μžκ°€ ν¬ν•¨λœ λͺ¨λ“  방을 κ°€μ Έμ˜€λ €λ©΄ chatroom λͺ¨λΈμ—μ„œ κ°€μ Έμ˜€κ³  싢은 μ‚¬μš©μžκ°€ μ†‘μ‹ μžμΌλ•Œ, μˆ˜μ‹ μžμΌλ•Œ λͺ¨λ‘ κ°€μ Έμ™€μ„œ Queryset을 합쳐야 ν•œλ‹€.
κ²€μƒ‰ν•΄λ³΄λ‹ˆ chainμ΄λΌλŠ” 것이 μžˆμ—ˆκ³  μ‰½κ²Œ κ΅¬ν˜„ν•  수 μžˆμ—ˆλ”°.

model μ½”λ“œ

class ChatRoom(models.Model):
    sender = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name='Room_sender')
    receiver = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name='Room_receiver')

    def __str__(self):
        return str(f'id : {self.id}, sender : {self.sender}, receiver : {self.receiver}')

view μž‘μ„± μ½”λ“œ

opponent_receiver = ChatRoom.objects.filter(sender=cur_user_id)
opponent_sender = ChatRoom.objects.filter(receiver=cur_user_id)

temp_opp_receiver = [User.objects.get(email=x.receiver) for x in opponent_receiver]
temp_opp_sender = [User.objects.get(email=x.sender) for x in opponent_sender]

result_opp_user = list(chain(temp_opp_receiver, temp_opp_sender))

slz = UserListSerializer(result_opp_user, many=True)

μ½”λ“œλ₯Ό λ‹€ 짜고 μƒκ°ν•΄λ³΄λ‹ˆ μ±„νŒ…μ΄ 온 μˆœμ„œλŒ€λ‘œ 정렬을 ν•΄μ£Όμ–΄μ•Ό ν•œλ‹€...
κ·Έ μ½”λ“œλŠ” λ°”λ‘œ λ– μ˜€λ₯΄μ§€λŠ” μ•Šκ³  쑰금 생각을 ν•˜κ³  λ‹€μ‹œ μ§œλ³΄μ•„μ•Ό 될 것 κ°™λ‹€.

profile
Carrot_hyeong

0개의 λŒ“κΈ€