顶部目录
Django+channels -> websocket
学习视频: https://www.bilibili.com/video/BV1J44y1p7NX/?p=10
学习记录截图: https://blog.csdn.net/qq_22038327/article/details/128586353
workon # 查看虚拟环境
mkvirtualenv web -p python3.10 # 创建虚拟环境
workon web # 进入虚拟环境
pip install django==4.1.5
pip install channels==4.0.0
pip install daphne==4.0.0
pip install black==22.12.0 # format code
django-admin startproject ws_demo
cd ws_demo
python manage.py startapp app01
ws_demo.setings.py
# 注册channels
INSTALLED_APPS = [
'daphne', # 放在 top 的位置
'channels',
'django.contrib.admin',
...
]
TEMPLATE = BASE_DIR.joinpath('app01/template')
TEMPLATES = [
{...
'DIRS': [TEMPLATE],
}...
]
# WSGI_APPLICATION = 'ws_demo.wsgi.application'
# 添加 ASGI_APPLICATION
ASGI_APPLICATION = 'ws_demo.asgi.application'
启动server
python manage.py migrate
python manage.py runserver
http 相关的py内容
app01.views.py
from django.shortcuts import render
def index(requests):
return render(requests, 'index.html')
ws_demo.urls.py
from app01.views import index
urlpatterns = [
path('admin/', admin.site.urls),
path('', index),
]
index.html
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
<style>
.msg{
height: 100%;
width: 50%;
border: 1px solid #dddddd;
}
</style>
</head>
<body>
<div class="msg", id="msg"></div>
<div>
<input type="text" placeholder="input" id="txt">
<input type="button" value="send">
</div>
</body>
</html>
websocket 相关的py内容
app01.consumers.py (相当于views)
import sys
from channels.generic.websocket import WebsocketConsumer
from channels.exceptions import StopConsumer
class ChatConsumer(WebsocketConsumer):
def websocket_connect(self, message):
print(sys._getframe().f_code.co_name)
self.accept()
# return super().websocket_connect(message)
def websocket_receive(self, message):
print(sys._getframe().f_code.co_name)
msg = message['text']
if msg == 'close':
self.close()
return
msg_server = f'{msg} servered...'
self.send(msg_server)
return super().websocket_receive(message)
def websocket_disconnect(self, message):
print(sys._getframe().f_code.co_name)
raise StopConsumer()
return super().websocket_disconnect(message)
app01.routings.py (相当于urls)
from django.urls import re_path
from .consumers import ChatConsumer
websocket_urlpatterns = [
re_path(r'ws/(?P<group>\w+)/$', ChatConsumer.as_asgi())
]
ws_demo.asgi.py
import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from app01.routings import websocket_urlpatterns
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ws_demo.settings')
# application = get_asgi_application()
application = ProtocolTypeRouter(
{
'http': get_asgi_application(),
'websocket': URLRouter(websocket_urlpatterns),
}
)
postman 测试 websocket 接口
在浏览器中实现http+websocket
index.html
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
<style>
.msg{
height: 100%;
width: 50%;
border: 1px solid #dddddd;
}
</style>
</head>
<body>
<div class="msg", id="msg"></div>
<div>
<input type="text" placeholder="input" id="txt">
<input type="button" value="send" onclick="sendMsg()">
<input type="button" value="close" onclick="closeCon()">
</div>
</body>
<script>
function txtShow(content){
var tag = document.createElement("div")
tag.innerText = content
document.getElementById("msg").append(tag)
}
socket = new WebSocket("ws://127.0.0.1:8000/ws/room/")
socket.onopen = function(event){
txtShow('[onOpen]')
}
socket.onmessage = function(event){
txtShow(event.data)
}
socket.onclose = function(event){
txtShow('[onClose]')
}
function sendMsg(){
var tag = document.getElementById("txt")
txtShow(tag.value)
socket.send(tag.value)
}
function closeCon(){
txtShow('close')
socket.send('close')
}
</script>
</html>