장고의 채널로 만드는 간단한 채팅 앱
Django에서는 Channels 라는 기능을 사용하면 WebSocket을 사용한 채팅 앱 등을 만들 수 있습니다.
Channels는 Django에서 비동기 통신 뷰를 실현하는 기능입니다.
채널은 HTTP뿐만 아니라 다양한 프로토콜을 지원합니다.
예를 들어 WebSocket, MQTT, chatbots 등입니다.
Channels는 채널이라고 불리는 데이터 구조가 핵이 되고 이것의 실체는 FIFO 큐입니다.
논리적으로는 Go의 channels와 비슷합니다.
이 글에서는 즉시 간단한 채팅 앱을 만들면서 장고의 채널을 살펴 보겠습니다.
Channels 설치
먼저 pip를 사용해서django channels를 설치합니다.
$ pip install django
$ pip install channels
Channels는 장고의 기능 (응용 프로그램)이므로 장고는 필수입니다.
사이트 만들기
pip에서 django설치하면 django-admin사용할 수 있습니다.
django-admim을 사용해서 사이트를 만듭니다.
이번에는 mysite사이트 (프로젝트)를 만듭니다.
$django-admin startproject mysite
channels 설치
mysite/settings.py편집기에서 열고 INSTALLED_APPS편집하고 channels설치하십시오.
이렇게하면 장고에서 채널을 사용할 수 있습니다.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.sta,
'channels', # 추가
]
asgi.py 편집
장고는 비동기 통신 asgi.py을 사용합니다.
이를 위해 mysite/asgi.py다음과 같이 편집합니다.
# mysite/asgi.py
import os
from channels.routing import ProtocolTypeRouter
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE' ,'mysite.settings')
application = ProtocolTypeRouter ({
'http':get_asgi_application()
})
이 편집은 http프로토콜에 애플리케이션을 대응시키기 위한 것입니다.
다른 프로토콜에 ProtocolTypeRouter대한 인수를 추가하여 편집할 수 있습니다.
이번은 http프로토콜에만 대응합니다.
ASGI_APPLICATION 정의
mysite/settings.py의 마지막 쪽 ASGI_APPLICATION을 정의합니다.
ASGI_APPLICATION의 값은 mysite.asgi.application됩니다.
이번은 mysite라는 사이트(프로젝트)명으로 하고 있으므로 ↓와 같이 정의하고 있습니다.
...
ASGI_APPLICATION = 'mysite.asgi.application'
채팅 앱 만들기
manage.py에서 앱을 만듭니다.
이번에는 채팅이라는 것이므로 앱 이름은 chat되어 있습니다.
$python manage.py startapp chat
chat앱을 만들면 ↓와 같은 디렉토리 구조로되어 있지만, 이번에는 거의 필요하지 않습니다.
chat
├── admin.py
├── apps.py
├── __init__.py
├── migrations
│ └── __init__.py
├── models.py
├── tests.py
└── views.py
1 directory, 7 files
따라서 ↓처럼 파일을 청소합니다.
사용하는 것은 __init__.py과 views.py만합니다.
chat
├── __init__.py
└── views.py
0 directories, 2 files
채팅 앱 설치
chat응용 프로그램을 만든 후 mysite/settings.py에 INSTALLED_APPS다시 편집합니다.
↓와 같이 chat앱을 설치합니다.
INSTALLED_APPS=[
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'channels',
'chat', # <------------------- 이것
]
페이지 만들기
chat앱 페이지를 만듭니다.
chat아래에 templates/chat디렉토리를 작성하고 그 안에 index.html를 정의하십시오.
chat
├── __init__.py
├── templates
│ └── chat
│ └── index.html # <-------- 이것 만들기
└── views.py
이 index.html페이지는 채팅 입장 페이지입니다.
사용자는 채팅방에 입실하여 채팅을 합니다.
index.html는 ↓과 같이 정의합니다.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>간단한 채팅에 입실하기</title>
</head>
<body>
<label>입장할 채팅방 이름:</ label>
<input id="room-name-input" type="text" size="100">
<input id="room-name-submit"type="button" value="입실">
<script>
// 채팅방에 들어가는 로직
const submit = document.querySelector('#room-name-submit')
input.focus() // 포커스를 입력란에 설정
input.onkeyup = (ev) => {
if (ev.keyCode === 13) {
// ENTER 키를 누르면 입실 버튼을 누른다
submit.click()
}
}
submit.onclick = (ev) => {
// 입장 버튼이 클릭되면 입력 된 대화방 이름의 페이지 (경로)로 이동
window.location.pathname = '/chat/' + input.value + '/'
}
</script>
</body>
</html>
chat/views.py 편집
chat/views.py을 ↓처럼 편집합니다.
from django.shortcuts import render
def index(request):
return render(request, 'chat/index.html')
index라는 뷰를 만들어 방금 만든 templates/chat/index.html것을 그립니다.
라우팅 설정
그런 다음 경로와 뷰를 연결하기 위해 라우팅을 구성합니다.
우선 mysite/urls.py을 ↓과 같이 편집합니다.
# mysite/urls.py
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls ),
path('chat/', include('chat.urls'))
]
/chat/에 액세스 chat하는 urls.py처리를 맡기고 있습니다.
그런 다음 chat/urls.py만들고 ↓처럼 편집합니다.
from django.urls import path
from chat.views import index
urlpatterns = [
path('' , index , name='index'),
]
브라우저에서 동작 확인
지금까지 코드가 움직이는지 여부를 개발 서버에서 테스트합니다.
runserver명령으로 개발 서버를 시작합니다.
python manage.py runserver 0.0.0.0:9999
그리고 브라우저에서 http://localhost:9999/chat/액세스합니다.
'python > Django' 카테고리의 다른 글
Django 커스텀 커맨드 만들기 (1) | 2021.12.04 |
---|---|
Django의 Meta 클래스 사용법 [ordering, db_table, verbose_name, etc] (0) | 2021.12.03 |
Django ORM distinct() (0) | 2021.12.03 |
Django values, valuse_list (0) | 2021.12.03 |
Django transaction atomic (0) | 2021.10.07 |
댓글