Django
django Chennels 활용 Websocket 통신 # 1 (세팅 및 테스트)
JOOHUUN
2022. 7. 16. 16:17
기존에 하던 프로젝트에서 진행
pip install channels 후 setting.py에 앱 추가
django-admin start app dm: dm 앱 생성
# project/settings.py
INSTALLED_APPS = [
'channels' # 패키지 설치후 엡에 등록하기
'user',
'article',
'dm',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'corsheaders',
'rest_framework',
'rest_framework_simplejwt',
]
2. 채널 레이어 설정
# project/settings.py
# INSTALL APP 밑부분에 추가
ASGI_APPLICATION = 'mywebsite.asgi.application'
CHANNEL_LAYERS = {
'default':{
'BACKEND':'channels.layers.InMemoryChannelLayer'
}
}
3. project/asgi.py
# project/asgi.py
import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
import chat.routing
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mywebsite.settings')
application = ProtocolTypeRouter({
'http':get_asgi_application(),
'websocket':AuthMiddlewareStack(
URLRouter(
chat.routing.websocket_urlpatterns
)
)
})
4. dm/consumers.py 에서 api 작성
# dm/consumers.py
import json
from channels.generic.websocket import WebsocketConsumer
from asgiref.sync import async_to_sync
class ChatConsumer(WebsocketConsumer):
def connect(self):
self.room_group_name = 'test'
async_to_sync(self.channel_layer.group_add)(
self.room_group_name,
self.channel_name
)
self.accept()
def receive(self, text_data):
print("recieve")
text_data_json = json.loads(text_data)
message = text_data_json['message']
print(message)
async_to_sync(self.channel_layer.group_send)(
self.room_group_name,
{
'type':'chat_message',
'message':message
}
)
def chat_message(self, event):
print("asdsd")
message = event['message']
self.send(text_data=json.dumps({
'type':'chat',
'message':message
}))
5. dm/routing.py
- consumers.py 에서 작성한 API의 라우팅(url) 설정
# dm/routing.py
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r'ws/socket-server/', consumers.ChatConsumer.as_asgi())
]
6. frontend 작성 및 테스트
# index.html
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Lobby</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
</head>
<body>
<h1>Lets chat!</h1>
<form id="form">
<input type="text" name="message" />
</form>
<div id="messages"></div>
<script src="/test.js"></script>
</body>
</html>
# test.js
let url = 'ws://127.0.0.1:8000/ws/socket-server/'
const chatSocket = new WebSocket(url)
chatSocket.onopen = () => chatSocket.send(JSON.stringify({
'event_pk': event_pk,
'participant_pk': 1,
'isConnected': 'true',
}));
chatSocket.onmessage = function (e) {
let data = JSON.parse(e.data)
console.log('Data:', data)
if (data.type === 'chat') {
let messages = document.getElementById('messages')
messages.insertAdjacentHTML('beforeend', `<div>
<p>${data.message}</p>
</div>`)
}
}
let form = document.getElementById('form')
form.addEventListener('submit', (e) => {
e.preventDefault()
let message = e.target.message.value
chatSocket.send(JSON.stringify({
'message': message
}))
form.reset()
})