본문 바로가기
프로그래밍/Python

[Python] Ubuntu + Django를 활용하여 채팅 프로그램 만들기 2편 ::우주를놀라게하자

by 우주를놀라게하자 2019. 7. 16.
반응형
SMALL

2. 채팅 서버 구축


새 폴더,파일을 만듭니다 chat/templates/chat/index.html앱 디렉토리는 다음과 같다.


templates로 만드는 이유는 django자체에서 templates라는 폴더를 인식하게끔 되어 있기 때문에 이름은 맞춰주고 하위에 app과 같은 이름의 폴더를 만들고 내부에 우리가 만들 페이지의 html을 구성해준다.

chat/ __init__.py templates/ chat/ index.html urls.py views.py

chat앱이 설치 되었다는 사실을 프로젝트에 알릴 필요가 있다. 편집 DjangoChat/settings.py파일을 추가합니다 'chat'받는 INSTALLED_APPS 에 우리가 만든 app 즉, chat을 추가해서 최상위 프로젝트에게 알려줍니다.

# mysite/settings.py
INSTALLED_APPS = [
    'chat',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]


다음에서 index.html에 대한 뷰 템플릿을 만듭니다 chat/templates/chat/index.html.

<!-- chat/templates/chat/room.html -->
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <title>Chat Room</title>
</head>
<body>
    <textarea id="chat-log" cols="100" rows="20"></textarea><br/>
    <input id="chat-message-input" type="text" size="100"/><br/>
    <input id="chat-message-submit" type="button" value="Send"/>
</body>
<script>
    var roomName = {{ room_name_json }};

    var chatSocket = new WebSocket(
        'ws://' + window.location.host +
        '/ws/chat/' + roomName + '/');

    chatSocket.onmessage = function(e) {
        var data = JSON.parse(e.data);
        var message = data['message'];
        document.querySelector('#chat-log').value += (message + '\n');
    };

    chatSocket.onclose = function(e) {
        console.error('Chat socket closed unexpectedly');
    };

    document.querySelector('#chat-message-input').focus();
    document.querySelector('#chat-message-input').onkeyup = function(e) {
        if (e.keyCode === 13) {  // enter, return
            document.querySelector('#chat-message-submit').click();
        }
    };

    document.querySelector('#chat-message-submit').onclick = function(e) {
        var messageInputDom = document.querySelector('#chat-message-input');
        var message = messageInputDom.value;
        chatSocket.send(JSON.stringify({
            'message': message
        }));

        messageInputDom.value = '';
    };
</script>
</html>

에서 룸 뷰의 뷰 기능을 생성합니다 chat/views.py index뷰 기능을 추가한다. 이 과정은 우리가 처음만든 django-admin에서 만든 최상위 폴더인, DjangoChat에서 부터 하위 app으로 들어가는 경로를 만들어주기 위함이다.

# chat/views.py from django.shortcuts import render def index(request): return render(request, 'chat/index.html', {})

최상위 프로젝트(DjangoChat)의 위치에서 index 경로를 만들자 DjangoChat/urls.py.

*python3의 django와 python2의 django가 다르므로 가급적이면 python3의 django를 사용하길 바란다.(형식이 좀 다름...)

# DjangoChat/urls.py from django.contrib import admin

from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls),

path('chat/', include('chat.urls', namespace='chat')),
]

위의 최상위 project에서 chat으로 넘어가게끔, 경로를 만들어주고, 우리가 만든 app에서 각각의 html로 넘어가게끔 경로를 잡아준다.

# chat/urls.py from django.contrib import admin

from django.urls import path, include app_name = 'chat'

urlpatterns = [ path('', index, name='index'),

]

실행 전 데이터베이스에 데이터 구조를 알려주고 서버를 시작해야한다. 아래 명령어를 실행하자.


 bash

$  python manage.py migrate


이 작업은 데이터베이스 데이터 구조를 반영하는 과정이다.


이제 실행을 한번 해보게 되면 


 bash

$  python manage.py runserver



위와 같은 형식의 페이지가 실행된다.



3. 채널 라이브러리 통합


Django-Channels 는 Django 내에서 HTTP 프로토콜이 아닌 다른 프로토콜들을 사용할 수 있게 해준다. 일반적으로는 Websocket을 사용하기 위해 많이 쓰이는 듯 하다.

pycharm_deployment

위 그림은 Django가 일반적으로 Request/Response를 다루는 방식이다. 클라이언트는 Request를 보내고, Django는 클라이언트로 돌려보낼 Response를 담고 있는 View를 호출한다.

Websocket은 위와 같은 요청처리 방식에서는 Websocket을 사용할 수 없다. 이를 위해 Channels 가 존재한다.

pycharm_deployment

Channels를 사용하게 되면 Django 는 위와 같은 구조로 작동하게 된다.

중간에 Channel Layer라는 것이 생겨서 일반적인 HTTP Request/Response 외에도 Websocket message들도 처리할 수 있게 된다.

참고로 Channels에서는 기존의 WSGI와는 다른 ASGI라는 것이 등장한다. ASGI WSGI와 유사하지만 더 많은 프로토콜 유형들을 지원함으로써 Websocket 통신이 가능하게 한다.



먼저 채널에 대한 루트 라우팅 구성을 만들어 보겠습니다. 채널 라우팅 설정 은 Django URLconf와 비슷하지만, 채널 서버가 HTTP 요청을 수신했을 때 실행할 코드를 채널에 알려줍니다.

일단 channels부터 설치를 하도록하자.

3.1 install channel

 bash

 $ pip install channels


빈 라우팅 구성부터 시작하겠습니다. 파일을 DjangoChat/routing.py만들고 다음 코드를 포함시킵니다.

# mysite/routing.py
from channels.routing import ProtocolTypeRouter

application = ProtocolTypeRouter({
    # (http->django views is added by default)
})

이제 위와 같은 방법으로 설치된 앱 목록에 채널 라이브러리를 추가하자. DjangoChat/settings.py파일을 편집하고 설정에 추가 'channels'하면,INSTALLED_APPS의 구성이 다음과 같아 진다. 

# mysite/settings.py
INSTALLED_APPS = [
    'channels',
    'chat',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

루트 라우팅 구성에서 채널을 가리켜 야합니다. DjangoChat/settings.py파일을 다시 편집하고 아래에 다음을 추가하십시오.

# mysite/settings.py
# Channels
ASGI_APPLICATION = 'DjangoChat.routing.application'

현재 설치된 앱에 채널이 있으면 runserver표준 Django 개발 서버를 채널 개발 서버로 대체하여 명령 을 제어하게된다 .

채널 개발 서버가 올바르게 작동하는지 확인하자. 다음 명령을 실행하자.

bash 

 $python manage.py runserver




Starting ASGI/Channels development server at http://127.0.0.1:8000/  이 줄에 집중해보면,  채널 개발 서버가 Django 개발 서버를 이어 받았다는 것을 나타냅니다.


이로써 기존의 Django가 제공하는 Request/Response에서 실시간으로 양방향 통신을 할 수 있게 되었다.




전체적으로 다시 한번 설명하자면, 실시간 채팅을 하기 위해선 기존의 Django에서 제공하는 Request/Response방식으로는 무리가 있다. 왜? 단방향으로 통신하기 때문에 요청을 주는 경우가 아니면 네트워크가 끊기는 문제가 있기 때문이다. 이러한 이유 때문에 지속적인 네트워킹이 필요했고 그걸 보완하기 이용한 것이 WebSocket 방식이다. 그러나 이러한 방식은 다른 형태의 프로토콜이기 때문에 우리는 다른형태의 프로토콜을 사용하기 위해서 Channels을 설치하여 사용하는 것이다.


channel 구축까지만 하고 통신을 준비가 됬으면 목표도달이다.!

반응형
LIST