しばらくあれこれとやっていて間が空いてしまいましたが、ようやくローカルで動かすことに成功したので書き留めておきましょう。
注意:こちらのページは、作成者seijiが勉強も兼ねてとの意味合いで、インターネットの情報をもとにトライした記録です。正常な動作を保証する事は一切致しかねます。
環境
使用端末:MacbookPro (OS:Catalina10.15.7)
ITerm2
shell : zsh
Python: ver 3.8.8
Django: ver 4.0
Channels: ver 3.0.4
channels-redis: ver 3.3.1
・Mac上で仮想環境を構築し、Django,Channels,WebSocketを利用。
・SERVER : WEBサーバ ➡️ Djangoを利用し、仮想ローカルサーバを設定。
キャッシュサーバ ➡️ Redis をインストール。
・ DATABASE : SQLite3
仮想環境の設定
チャットアプリ用のディレクトリ「Mychat」を作成し、Mychatへ移動
%cd MychatMychat上でPythonの仮想環境を構築
Mychat% python -m venv .venv構築した仮想環境上に移動
Mychat% source .venv/bin/activate注)MacOSの場合。Windowsの場合は、.venv/Scripts/activate.bat となる模様。
➡️ターミナルでのプロンプト先頭に、(.venv)と表示される。
終了する場合は、「deactivate」コマンドを実行。
Pythonパッケージの一括インストール
目的:使用するPythonパッケージ(Django,Channels,channels-redis)を一括でインストールする。
①「Mychat」ディレクトリの下に、「requirement.txt」ファイルを作成
django
channels
channels-redis②ターミナル上で、下記コマンドを実行
% python -m pip install -r requirement.txt③下記コマンドを実行し、インストールされたパッケージを確認。
% python -m pip freeze
Djangoプロジェクトの作成
「Mychat」ディレクトリにて下記コマンドを実行し、Djangoプロジェクト「mysite」を作成。
Mychat% django-admin startproject mysite「mysite」に移動。
Mychat% cd mysite「mysite」ディレクトリにて下記コマンドを実行し、サーバーを起動。
mysite% python manage.py runserver
注)上記、6行目「ASGI/Channels version 3.0.4」は、Channels有効化後に表示されます。
この状態で、ブラウザにてローカルホスト「127.0.0.1:8000」にアクセスすると、Djangoのインストール完了画面が表示される。
Djangoアプリケーションの作成
「mysite」ディレクトリにてDjangoアプリケーションを作成
% python manage.py startapp chat作成したアプリケーションを、Djangoプロジェクトに登録。
「mysite/mysite/settings.py」の、「INSTALLED_APPS」の最上部に追記。
INSTALLED_APPS = [
'chat',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]chat.htmlの作成
htmlファイルを作成。 (Mychat/mysite/chat/templates/chat)
chat% vim chat.html <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Chat</title>
</head>
<body>
<h1>Chat</h1>
<form action="" onsubmit="onsubmitButton_Send();return false;">
Message:<input type="text" id="input_message" autocomplete="off" autofocus/><input type="submit" value="Send" />
</form>
<ul id="list_message"></ul>
<script>
const g_elementInputMessage = document.getElementById("input_message");
const g_elementListMessage = document.getElementById("list_message");
//Websocketオブジェクト
let ws_scheme = window.location.protocol == "https:" ? "wss" : "ws";
const g_socket = new WebSocket(ws_scheme + "://" + window.location.host + "/ws/chat/");
//「Send」ボタンを押したときの処理
function onsubmitButton_Send()
{
//送信用テキストHTML要素からメッセージ文字列の取得
let strMessage = g_elementInputMessage.value;
if( !strMessage )
{
return;
}
//WebSocketを通したメッセージの受信
g_socket.send(JSON.stringify({"message":strMessage}));
//送信用テキストHTML要素の中身のクリア
g_elementInputMessage.value = "";
}
//Websocketからのメッセージ受信時の処理
g_socket.onmessage = (event) =>
{
//テキストデータをJSONデータにデコード
let data = JSON.parse(event.data);
//メッセージの整形
let strMessage = data["message"];
//拡散されたメッセージをメッセージリストに追加
let elementLi = document.createElement("li");
elementLi.textContent = strMessage;
g_elementListMessage.prepend(elementLi); //リストの一番上に追加
//g_elementListMessage.append(elementLi); //リストの一番下に追加
};
//Websocketクローズ時の処理
g_socket.onclose = (event) =>
{
//ウェブページを閉じた時以外のWebsocketクローズは想定外
console.error("Unexpected : Chat socket closed.");
};
</script>
</body>
</html>
chat.html を表示させるための関数を「views.py」に追記。(mysite/chat/views.py)
from django.shortcuts import render
# Create your views here.
def chat( request ):
return render( request, 'chat/chat.html' )
作成した関数を呼び出すURLパターンを定義。(mysite/chat)
「urls.py」を新規作成。
from django.urls import path
from . import views
urlpatterns = [
path( '', views.chat, name='chat' ),
]
プロジェクトの「urls.py」に追記。(Mychat/mysite/mysite/urls.py)
・from django.urls import include #include関数をimport
・path(”, include(‘chat.urls’)), #アプリケーションの「urls.py」へパスを通す
・・・省略・・・
from django.contrib import admin
from django.urls import path
from django.urls import include
urlpatterns = [
path( '', include( 'chat.urls' ) ),
path('admin/', admin.site.urls),
]Channelsパッケージをプロジェクトへ登録
ChannelsパッケージをDjangoプロジェクトに登録。
「mysite/mysite/settings.py」の、「INSTALLED_APPS」の最上部に追記。
INSTALLED_APPS = [
'channels',
'chat',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]ルーティングに関するコードの追加
下記コードを追記する。(mysite/mysite/asgi.py)
・django_asgi_app = get_asgi_application() #変数名の変更
・from channels.routing import ProtocolTypeRouter #ProtocolTypeRouterをimport
・application = ProtocolTypeRouter(… #applicationの設定コードをProtocolTypeRouterクラスを用いて記述
・・・省略・・・
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
#application = get_asgi_application()
django_asgi_app = get_asgi_application()
from channels.routing import ProtocolTypeRouter
application = ProtocolTypeRouter( {
'http': django_asgi_app,
} )
「mysite/mysite/settings.py」の最下部に下記を追記。
# Channels
ASGI_APPLICATION = 'mysite.asgi.application'いったんここまででひと休みしましょう。
続いては、
・Redisの有効化
・メッセージ送受信のためのchat.htmlファイル及びconsumers.pyファイルの作成
となります。
注意:こちらのページは、作成者seijiが勉強も兼ねてとの意味合いで、インターネットの情報をもとにトライした記録です。正常な動作を保証する事は一切致しかねます。
