바뀜

둘러보기로 가기 검색하러 가기
1번째 줄: 1번째 줄:  
== 개요 ==
 
== 개요 ==
https://victorydntmd.tistory.com/261<nowiki/>를 참고하였다.
+
https://channels.readthedocs.io/en/latest/index.html<nowiki/>를 참고하였다.
    
장고는 기본적으로 동기식으로, 채팅을 위해선 비동기식 처리가 필요하다.
 
장고는 기본적으로 동기식으로, 채팅을 위해선 비동기식 처리가 필요하다.
131번째 줄: 131번째 줄:  
|}
 
|}
   −
=== 채팅룸 구현 ===
+
== 채팅룸 구현 ==
 
{| class="wikitable"
 
{| class="wikitable"
 
!과정
 
!과정
142번째 줄: 142번째 줄:  
urlpatterns = [
 
urlpatterns = [
 
     ...
 
     ...
     path('<str:roomname>/', views.room, name='room'),
+
     path('<str:room_name>/', views.room, name='room'),
 
     ...
 
     ...
 
]
 
]
149번째 줄: 149번째 줄:  
|뷰 작성
 
|뷰 작성
 
|room 뷰 작성
 
|room 뷰 작성
 +
mark_safe와 json을 가져온다.
 
|<syntaxhighlight lang="python">
 
|<syntaxhighlight lang="python">
urlpatterns = [
+
from django.shortcuts import render
     ...
+
from django.utils.safestring import mark_safe
     path('<str:roomname>/', views.room, name='room'),
+
import json
    ...
+
 
 +
def room(request, room_name):
 +
    return render(request, 'chat/room.html', {
 +
        'room_name_json': mark_safe(json.dumps(room_name))
 +
    })
 +
</syntaxhighlight>
 +
|-
 +
|탬플릿 작성
 +
|/char/room.html을 만든다.
 +
|<syntaxhighlight lang="html+django">
 +
<!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>
 +
</syntaxhighlight>
 +
|}
 +
 
 +
=== 참가자 구현 ===
 +
{| class="wikitable"
 +
!과정
 +
!설명
 +
!방법
 +
|-
 +
|참가자 파일 작성
 +
|/chat/consumers.py 작성.
 +
모든 요청을 받아들이는 비동기적인 웹소켓.
 +
 
 +
클라이언트로부터 메시지를 받아서 그대로 전달.
 +
|<syntaxhighlight lang="python">
 +
from channels.generic.websocket import WebsocketConsumer
 +
import json
 +
 
 +
class ChatConsumer(WebsocketConsumer):
 +
    def connect(self):
 +
        self.accept()
 +
 
 +
    def disconnect(self, close_code):
 +
        pass
 +
 
 +
    def receive(self, text_data):
 +
        text_data_json = json.loads(text_data)
 +
        message = text_data_json['message']
 +
 
 +
        self.send(text_data=json.dumps({
 +
            'message': message
 +
        }))
 +
</syntaxhighlight>
 +
|-
 +
|라우팅 작성
 +
|/chat/routing.py 작성
 +
|<syntaxhighlight lang="python">
 +
from django.conf.urls import url
 +
from . import consumers
 +
 
 +
websocket_urlpatterns = [
 +
    url(r'^ws/chat/(?P<room_name>[^/]+)/$', consumers.ChatConsumer),
 
]
 
]
 +
</syntaxhighlight>
 +
|-
 +
|라우팅 등록
 +
|/routing.py 수정
 +
chat 안의 라우팅을 등록해준다.
 +
 +
그리고 임포트하는 모듈을 수정해준다.
 +
|<syntaxhighlight lang="python">
 +
from channels.auth import AuthMiddlewareStack
 +
from channels.routing import ProtocolTypeRouter, URLRouter
 +
import chat.routing
 +
 +
application = ProtocolTypeRouter({
 +
    # (http->django views is added by default)
 +
    'websocket': AuthMiddlewareStack(
 +
        URLRouter(
 +
            chat.routing.websocket_urlpatterns
 +
        )
 +
    ),
 +
})
 +
</syntaxhighlight>
 +
|}
 +
여기까지 하고 채팅을 쳐 보면... 채팅이 나와야 정상.
 +
 +
=== 체널레이어 구현 ===
 +
{| class="wikitable"
 +
!과정
 +
!설명
 +
!방법
 +
|-
 +
|패키지 설치
 +
|Channels가 Redis인터페이스를 인식하도록.
 +
|pip install channels_redis
 +
|-
 +
|settings.py 설정
 +
|ASGI 아래 추가하자.
 +
|<syntaxhighlight lang="python">
 +
ASGI_APPLICATION = 'routing.application'  # routing.py 파일의 application을 불러온다.
 +
CHANNEL_LAYERS = {
 +
    'default': {
 +
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
 +
        'CONFIG': {
 +
            "hosts": [('127.0.0.1', 6379)],
 +
        },
 +
    },
 +
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 
|}
 
|}
 
[[분류:6. 장고 기능구현]]
 
[[분류:6. 장고 기능구현]]

둘러보기 메뉴