分享

[Python]Django 3.1.7 Websocket實作

只是記錄一下怕自己忘記。建構環境為Ubuntu 20.04.2 LTS
建構所需資料夾 
  

$mkdir django_websocket && cd django_websocket

建立虛擬環境 
  

$ python3 -m venv venv

啟動虛擬環境 
  

$source ./venv/bin/activate

安裝Django 
  

(venv)$pip install django

安裝websocket
  

(venv)$pip install websocket

安裝ASGI Server 
  

(venv)$pip install daphne

建立Django Project 
  

(venv)$django-admin startproject websocket_app

修改 /websocket_app/websocket_app/urls.py
  

#urls.py of project

from django.contrib import admin

from django.urls import path, include

from django.shortcuts import render, HttpResponse


def indexPage(request):

    return render(request, 'index.html')


urlpatterns = [

    path('', indexPage),

    path('admin/', admin.site.urls),

    path('home/', include('home.urls')),

]

修改 /websocket_app/websocket_app/asgi.py
  

import os

from django.core.asgi import get_asgi_application

from websocket_app.websocket import websocket_application


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


django_application = get_asgi_application()

async def application(scope, receive, send):

    if scope['type'] == 'http':

        await django_application(scope, receive, send)

    elif scope['type'] == 'websocket':

        await websocket_application(scope, receive, send)

    else:

        raise NotImplementedError(f"Unknown scope type {scope['type']}")

新增 /websocket_app/websocket_app/websocket.py
  

import time

async def websocket_application(scope, receive, send): 

    while True:

        event = await receive()

        if event['type'] == 'websocket.connect':

            await send({

                'type': 'websocket.accept'

            })

        if event['type'] == 'websocket.disconnect':

            break

        if event['type'] == 'websocket.receive':

            if event['text'] == 'currentTime':

                timeStamp = time.strftime('%Y-%m-%d %H:%M:%S')         

                await send({

                    'type': 'websocket.send',

                    'text': timeStamp

                })

            else:      

                await send({

                    'type': 'websocket.send',

                    'text': 'You tell me ' + event['text'] + ' but I dunno, Meeeeow'

                })

新增一個django APP 在websocket_app/ (和manage.py同一層)下
  

$ django-admin startapp home

修改/websocket_app/home/urls.py
  

#urls.py of home app

from django.urls import path

from . import views

import os

appName = 'home'

pagesInDIR = os.listdir('./templates/' + appName)

appendPages = []

for i in pagesInDIR:

    if i != 'index.html':

        if i[len(i)-5:] == '.html':

            appendPages.append(path(i[:len(i)-5], views.home))

urlpatterns_basic = [path('', views.home)]

urlpatterns = urlpatterns_basic + appendPages

修改/websocket_app/home/views.py
  

from django.shortcuts import render, HttpResponse

appName = 'home'

def home(request):

    target = (request.path).lstrip('/')

    if target == appName + '/':

        target = target + 'index.html'

    elif ('.html') not in target:

        target = target + '.html'

    return render(request, target)

修改/websocket_app/websocket_app/settings.py
新增一行
  

import os

原有
  

ALLOWED_HOSTS = []

改為
  

ALLOWED_HOSTS = ['*']

以利遠端存取測試 如果以Local端測試則不用改
  

TEMPLATES = [

    {

        'BACKEND': 'django.template.backends.django.DjangoTemplates',

        'DIRS': [],

下面還有一大串東西....

則改為
  

TEMPLATES = [

    {

        'BACKEND': 'django.template.backends.django.DjangoTemplates',

        'DIRS': [os.path.join(BASE_DIR, 'templates').replace('\\', '/')],

語言改為
  

LANGUAGE_CODE = 'zh-Hant'

時區改為
  

TIME_ZONE = 'Asia/Taipei'

在/websocket_app下新增資料夾templates
在/websocket_app/templates下新增檔案 index.html
  

<!DOCTYPE html>

<head>

<meta http-equiv = "Content-Type" content = "text/html; charset=utf-8" />

<title>Hello</title>


</head>

<body>

    <h1>Current Running Apps in This Django Server:</h1><br>

    <a href = "/home">Home</a>

</body>

</html>

在/websocket_app/templates下新增資料夾home
在/websocket_app/templates/home下新增檔案 index.html
  

<!DOCTYPE html>

<head>

<meta http-equiv = "Content-Type" content = "text/html; charset=utf-8" />

<title>Hello</title>


</head>

<body>

    <h1>Hello</h1>

    <h2>This is my first Django Page</h2>

    <a href = "ws">Websocket Test Page</a><br>

    <a href = "htm_test">Html Test Page</a>


</body>

</html>

在/websocket_app/templates/home下新增檔案ws.html
  

<!DOCTYPE html>

<head>

<meta http-equiv = "Content-Type" content = "text/html; charset=utf-8" />

<title>Hello</title>


</head>

<body>

    <h1>Hello</h1>

    <h2>This is my first Django Page with WebSocket</h2>

    Local Time:<span id = 'localTime'></span><br><br>

    Server Time: <span id = 'serverTime'></span><br><br>

    <a href = "/home">Back</a>

    <script language = "javascript">

        function showServerTime(){

            if (ws.readyState == 1){

                ws.send('currentTime');

            }

            else{

                document.getElementById('serverTime').textContent = 'WebSocket Disconnected';

            }

        }

        function showLocalTime(){

            var current = new Date();

            year = current.getFullYear().toString();

            month = (current.getMonth() + 1).toString();

            day = current.getDate().toString();

            hour = current.getHours().toString();

            minute = current.getMinutes().toString();

            second = current.getSeconds().toString();

            localD = year + '-' + completeZero(month, 2) + '-' + completeZero(day, 2);

            localT = completeZero(hour, 2) + ':' + completeZero(minute, 2) + ':' + completeZero(second, 2);

            localFullTime = localD + ' ' + localT;

            

            document.getElementById('localTime').textContent = localFullTime;

        }

        function completeZero(str, digits){

            for(var i = 1; i < digits; i++){

                str = (str.length >= digits ? '':'0') + str;

            }

            return str;

        }

        

        //Main Here Below         

        //var wsTargetIP = '192.168.100.11:8000'

        var wsTargetIP = location.host;

        var ws = new WebSocket('ws://' + wsTargetIP);

        ws.onmessage = event => document.getElementById('serverTime').textContent = event.data;

        setInterval(showServerTime,1000);

        setInterval(showLocalTime,1000);

    </script>


</body>

</html>

在/websocket_app/templates/home下新增檔案htm_test.html
  

<!DOCTYPE html>

<head>

<meta http-equiv = "Content-Type" content = "text/html; charset=utf-8" />


<title>HTML Test</title>


</head>

<body>

    <a href = "/home">Go Back</a>

    <p>color test</p>


    <p>I don&#39;t <span style="color:#e74c3c">know</span> if <span style="color:#f39c12">css</span> works or <span style="font-size:20px">NOT</span></p>

    中文測試中文測試中文測試中文測試中文測試中文測試中文測試中文測試中文測試中文測試中文測試中文測試中文測試中文測試中文測試中文測試中文測試中文測試中文測試中文測試中文測試中文測試中文測試

    <p><span style="font-size:20px"><input name="BTN" type="button" value="GO!" onclick = "oops();"/>

        <span style="font-size:20px"><input name="BTN" type="button" value="Make it back" onclick = "bbb();"/></span></p>

    <p>&nbsp;</p>

    

    <p><span style="color:#e74c3c" style="font-size:22px" id = 'amz'></span>&nbsp;will be change if you click on the button</p>



    <script language = "javascript">

        function oops(){

            document.getElementById('amz').textContent = 'Meeeeeeeoooowwww';

            alert('amazing!');

        }

        function bbb(){

            document.getElementById('amz').textContent = 'THIS';

            alert('amazing!We are back!!');

        }

        document.getElementById('amz').textContent = 'THIS';

    

    </script>


</body>

</html>

建構完成 在/websocket_app下啟動server
  

daphne websocket_app.asgi:application --b 0.0.0.0

預設port是8000 連結到 http://<server 的IP>:8000/home/ws
如果看得到server time 表示成功
#python3  #source  #Django  #websocket 
分類:學習

寫Code只是興趣 是個什麼都做的打雜小弟

評論
更多文章
載入中... 沒有更多了