20230308
[ 기존 채팅 내역 불러오기 ]
● HTML 수정 (웹소켓 연결할 때)
<script type="text/javascript">
let roomName = "{{ room_id | escapejs }}";
let to = "{{ to | escapejs }}";
# WebSocket 연결
let chatSocket = new WebSocket(
`ws://${window.location.host}/ws/chatroom/${roomName}/`
);
# WebSocket 연결되자마자 실행 (DB 불러오기)
chatSocket.onopen = (e) => {
chatSocket.send(JSON.stringify({'command' : 'return_messages'}))
};
# 채팅방 화면에 출력
chatSocket.onmessage = (e) => {
let data = JSON.parse(e.data);
# 기존 채팅 내역 불러오기
if (data['command'] == 'return_messages') {
let messages = data['messages'];
for (const i in messages) {
document.querySelector("#chat-log").value += (messages[i]['from_user'] + ' : ' + messages[i]['message'] + '\n');
}
}
# 새로운 채팅 입력
else {
let message = data['message'];
let from_user = data['from_user'];
document.querySelector("#chat-log").value += (from_user+' : ' + message + '\n');
}
};
chatSocket.onclose = (e) => {
console.error('Chat socket closed unexpectedly');
};
document.querySelector("#chat-message-input").focus();
document.querySelector("#chat-message-input").addEventListener("keyup",(e) => {
if (e.keyCode === 13) {
document.querySelector("#chat-message-submit").click();
}
});
# consumers.py 에 전달
document.querySelector("#chat-message-submit").addEventListener("click", (e) => {
let messageInputDom = document.querySelector("#chat-message-input");
let message = messageInputDom.value;
chatSocket.send(JSON.stringify({
'command': 'new_messages',
'message' : message,
'to_user' : to,
'from_user' : {{ request.session.user_uid }},
'room_id' : roomName
}));
messageInputDom.value = '';
});
</script>
● consumers.py 수정
import json
from channels.db import database_sync_to_async
from channels.generic.websocket import AsyncWebsocketConsumer
from chat01.models import Chatting
class ChatConsumer(AsyncWebsocketConsumer):
# WebSocket 연결될 때
async def connect(self):
self.room_name = self.scope["url_route"]["kwargs"]["room_id"]
self.room_group_name = "chat_%s" % self.room_name
# Join room group
await self.channel_layer.group_add(self.room_group_name, self.channel_name)
await self.accept()
async def disconnect(self, close_code):
# Leave room group
await self.channel_layer.group_discard(self.room_group_name, self.channel_name)
# js code에서 데이터 넘겨받기
async def receive(self, text_data):
data = json.loads(text_data)
await self.commands[data['command']](self, data)
# 새 채팅 입력
async def new_messages(self, text_data):
text_data_json = text_data
message = text_data_json["message"]
from_user = text_data_json["from_user"]
to_user = text_data_json["to_user"]
room_id = text_data_json["room_id"]
await self.save_message(to_user, from_user, message, room_id)
# Send message to room group
await self.channel_layer.group_send(
self.room_group_name, {"type": "chat_message", "from_user": from_user, "message": message}
)
# Receive message from room group
async def chat_message(self, event):
message = event["message"]
from_user = event["from_user"]
# Send message to WebSocket
await self.send(text_data=json.dumps({"command":"receive_message", "from_user": from_user, "message": message}))
# DB 저장
@database_sync_to_async
def save_message(self, to, from_user, message, room_id):
chatting = Chatting()
chatting.to = to
chatting.from_user = from_user
chatting.message = message
chatting.room_id = room_id
return chatting.save()
# 저장된 메세지 불러오기
async def return_message(self, data):
messages = await self.return_db()
content = {
'command': 'return_messages',
'messages': messages
}
await self.send(text_data=json.dumps(content))
@database_sync_to_async
def return_db(self):
result = Chatting.objects.filter(room_id=self.room_name)
messages = []
for message in result:
messages.append({'to_user': message.to, 'from_user': message.from_user, 'message': message.message})
return messages
commands = {
'return_messages': return_message,
'new_messages': new_messages
}
☞ 채팅 영상 ☜
'CLOUD > [P] 실시간 채팅 프로그램' 카테고리의 다른 글
[WebSocket/AWS] Terraform Code 작성 (0) | 2023.04.06 |
---|---|
[WebSocket/AWS] 주제 선정 (0) | 2023.04.05 |
[WebSocket/AWS] AWS Cloud Architecture 구상도 (0) | 2023.04.04 |
[WebSocket/Django] Chatting : DB 저장하기 (0) | 2023.03.23 |
[WebSocket/Django] 2계층 설계 + 템플릿 선정 (0) | 2023.03.22 |