websocket server client tutorial - pai-plznw4me/django-initializer GitHub Wiki

Web socket 튜토리얼

스크린샷 2022-05-23 오전 9 16 31 - 서버에서 message 을 보냅니다.

개요

  • 실시간으로 ping 상태를 통해 서버를 모니터링 할 수 있는 websocket tutorial 예제 입니다.

1. 프로젝트 시작

django-admin startproject websocket . 

2. 앱 만들기 및 연결

python manage.py startapp realtime_graph

2.1 프로젝트에 앱 연결

[
'django.contrib.admin',
'django.contrib.auth',
...
'realtime_graph', # <- 추가된 app
]

2.2 project url 에 app url 연결

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('realtime_graph.urls')),

]

3. Django channels app

3.1 설치

pip install channels

3.2 INSTALLED_APPS 에 추가하기

[
'django.contrib.admin',
'django.contrib.auth',
...
'channels', # <- 추가된 app
]

4. Client Websocket Html

4.1 html page 생성

  • 생성위치는 project level 에 templates 폴더 내 base.html 파일 생성
templates/base.html

4.2 Html

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <!-- CSS only -->
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"
          integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
    <title> Realtime Graph app </title>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-10 mx-auto mt-5">
            <h1 id="app">hello world</h1>
        </div>
    </div>
</div>

<script src='https://cdnjs.cloudflare.com/ajax/libs/reconnecting-websocket/1.0.0/reconnecting-websocket.js'></script>
<script src="{% static 'main.js' %}"></script>
</body>
</html>

4.3. Set default templates folder

# settigns.py
TEMPLATES = [
    {
        ...
        'DIRS': [BASE_DIR.joinpath('templates')], # <- settings
        ...
    },
]

5. javascript

5.1 생성

static/main.js

5.1

// var socket = new WebSocket('ws://localhost:8000/ws/graph/')
var socket = new WebSocket('ws://localhost:8000/ws/graph/')

socket.onmessage = function (e) {
    var djangoData = JSON.parse(e.data);
    console.log(djangoData);
    document.querySelector('#app').innerText = djangoData;
}

socket.onclose = () => {
    console.log('Web Socket Connection Closed');
    socket.close();
}

5.2. Set default static folder at Django settings.py

STATICFILES_DIRS = [
    BASE_DIR.joinpath('static'),
]

Consumers 생성

realtime_graph/consumers.py

import json
import subprocess
from channels.generic.websocket import WebsocketConsumer


class GraphConsumer(WebsocketConsumer):
    def connect(self):
        self.accept()

        p = subprocess.Popen(['ping', '127.0.0.1'], stdout=subprocess.PIPE)

        while True:
            line = p.stdout.readline().decode('utf-8')
            self.send(json.dumps(line))

Routing 생성

from django.urls import path
from realtime_graph.consumers import GraphConsumer

ws_urlpatterns = [
    path('ws/graph/', GraphConsumer.as_asgi())
]

ASGI

# websocket/asgi.py
import os

from channels.auth import AuthMiddlewareStack
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from realtime_graph.routing import ws_urlpatterns

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'websocket.settings')

application = ProtocolTypeRouter({
    'http': get_asgi_application(),
    'websocket': AuthMiddlewareStack(URLRouter(ws_urlpatterns))
})
# application = get_asgi_application()
# websocket/settings.py
ASGI_APPLICATION = 'websocket.asgi.application'

views.py

from django.shortcuts import render


def index(request):
    return render(request, template_name='base.html')

run & result

http://localhost:8000
스크린샷 2022-05-20 오후 5 44 46

reference

https://channels.readthedocs.io/en/stable/topics/channel_layers.html https://www.youtube.com/watch?v=tZY260UyAiE https://www.neerajbyte.com/post/how-to-implement-websocket-in-django-using-channels-and-stream-websocket-data https://antilibrary.org/1117 https://dbza.tistory.com/entry/10-%EC%9E%A5%EA%B3%A0-DRF%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-%EC%9B%B9-API-%EB%A7%8C%EB%93%A4%EA%B8%B04?category=903661 https://yongbbbba.github.io/til/djangoChannels/

⚠️ **GitHub.com Fallback** ⚠️