詳解Django-channels 實(shí)現(xiàn)WebSocket實(shí)例
引入
先安裝三個(gè)模塊
pip install channels pip install channels_redis pip install pywin32
創(chuàng)建一個(gè)Django項(xiàng)目和一個(gè)app
項(xiàng)目名隨意,app名隨意。這里項(xiàng)目名為 django_websocket_demo ,app名 chat
把a(bǔ)pp文件夾下除了 views.py 和 __init__.py 的文件都刪了,最終項(xiàng)目目錄結(jié)構(gòu)如下:
django_websocket_demo/
manage.py
django_websocket_demo/
__init__.py
settings.py
urls.py
wsgi.py
chat/
__init__.py
views.py
在app下新建一個(gè)templates文件夾用來存放HTML頁面:
chat/
__init__.py
templates/
chat/
index.html
views.py
index.html 內(nèi)容如下:
<!-- chat/templates/chat/index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Chat Rooms</title>
</head>
<body>
What chat room would you like to enter?<br/>
<input id="room-name-input" type="text" size="100"/><br/>
<input id="room-name-submit" type="button" value="Enter"/>
<script>
document.querySelector('#room-name-input').focus();
document.querySelector('#room-name-input').onkeyup = function(e) {
if (e.keyCode === 13) { // enter, return
document.querySelector('#room-name-submit').click();
}
};
document.querySelector('#room-name-submit').onclick = function(e) {
var roomName = document.querySelector('#room-name-input').value;
window.location.pathname = '/chat/' + roomName + '/';
};
</script>
</body>
</html>
在 chat/views.py 中添加視圖函數(shù):
from django.shortcuts import render
def index(request):
return render(request, 'chat/index.html', {})
添加 chat/urls.py 文件并設(shè)置路由信息:
from django.urls import re_path from . import views urlpatterns = [ re_path(r'^$', views.index, name='index'), ]
在項(xiàng)目路由 django_websocket_demo/urls.py 中配置路由信息:
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^chat/', include('chat.urls')),
url(r'^admin/', admin.site.urls),
]
在 settings.py 文件同級目錄下新建 routing.py 文件,內(nèi)容如下:
from channels.routing import ProtocolTypeRouter
application = ProtocolTypeRouter({
# (http->django views is added by default)
})
把 channels 注冊在 settings.py 里:
INSTALLED_APPS = [ 'channels', 'chat', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ]
在 settings.py 文件中,添加如下配置項(xiàng):
# django_websocket_demo/settings.py # Channels # Channels ASGI_APPLICATION = 'django_websocket_demo.routing.application'
創(chuàng)建聊天頁面
創(chuàng)建一個(gè) chat/templates/chat/room.html 文件,添加如下內(nèi)容:
<!-- chat/templates/chat/room.html -->
<!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>
在 chat/views.py 中添加一個(gè)處理 room的視圖函數(shù):
from django.shortcuts import render
from django.utils.safestring import mark_safe
import json
def index(request):
return render(request, 'chat/index.html', {})
def room(request, room_name):
return render(request, 'chat/room.html', {
'room_name_json': mark_safe(json.dumps(room_name))
})
在 chat/urls.py 中注冊路由
from django.urls import re_path from . import views urlpatterns = [ re_path(r'^$', views.index, name='index'), re_path(r'^(?P<room_name>[^/]+)/$', views.room, name='room'), ]
新建 chat/consumers.py 文件,添加如下內(nèi)容:
from channels.generic.websocket import AsyncWebsocketConsumer
import json
class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.room_name = self.scope['url_route']['kwargs']['room_name']
self.room_group_name = 'chat_%s' % self.room_name
# Join room group
await self.channel_layer.group_add(
self.room_group_name,
self.channel_name
)
await self.accept()
async def disconnect(self, close_code):
# Leave room group
await self.channel_layer.group_discard(
self.room_group_name,
self.channel_name
)
# Receive message from WebSocket
async def receive(self, text_data):
text_data_json = json.loads(text_data)
message = text_data_json['message']
# Send message to room group
await self.channel_layer.group_send(
self.room_group_name,
{
'type': 'chat_message',
'message': message
}
)
# Receive message from room group
async def chat_message(self, event):
message = event['message']
# Send message to WebSocket
await self.send(text_data=json.dumps({
'message': message
}))
新建一個(gè) chat/routing.py 文件,添加以下內(nèi)容:
from django.urls import re_path from . import consumers websocket_urlpatterns = [ re_path(r'^ws/chat/(?P<room_name>[^/]+)/$', consumers.ChatConsumer), ]
將 django_websocket_demo/routing.py 文件中修改為以下內(nèi)容:
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
)
),
})
配置redis
在本地6379端口啟動redis : redis-server
在 settings.py 中添加如下配置:
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [('127.0.0.1', 6379)],
},
},
}
最后啟動Django項(xiàng)目
使用多個(gè)瀏覽器打開http://127.0.0.1:8000/chat/lobby/ ,開始實(shí)時(shí)聊天吧。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Django實(shí)現(xiàn)WebSocket在線聊天室功能(channels庫)
- Django中如何使用Channels功能
- Django使用channels + websocket打造在線聊天室
- django使用channels實(shí)現(xiàn)通信的示例
- 淺談django channels 路由誤導(dǎo)
- Django使用Channels實(shí)現(xiàn)WebSocket的方法
- Django Channels 實(shí)現(xiàn)點(diǎn)對點(diǎn)實(shí)時(shí)聊天和消息推送功能
- django使用channels2.x實(shí)現(xiàn)實(shí)時(shí)通訊
- django channels使用和配置及實(shí)現(xiàn)群聊
相關(guān)文章
詳解APScheduler如何設(shè)置任務(wù)不并發(fā)
本文主要介紹了APScheduler如何設(shè)置任務(wù)不并發(fā),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
Python個(gè)人博客程序開發(fā)實(shí)例用戶驗(yàn)證功能
這篇文章主要介紹了怎樣用Python來實(shí)現(xiàn)一個(gè)完整的個(gè)人博客系統(tǒng),我們通過實(shí)操上手的方式可以高效的鞏固所學(xué)的基礎(chǔ)知識,感興趣的朋友一起來看看吧2022-12-12
Python參數(shù)傳遞實(shí)現(xiàn)過程及原理詳解
這篇文章主要介紹了Python參數(shù)傳遞實(shí)現(xiàn)過程及原理詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05
Python時(shí)間轉(zhuǎn)化方法超全總結(jié)
在生活和工作中,我們每個(gè)人每天都在和時(shí)間打交道。本文就為大家總結(jié)了Python實(shí)現(xiàn)時(shí)間轉(zhuǎn)化的多種方法,快來跟隨小編一起學(xué)習(xí)一下吧2022-03-03
pandas 如何保存數(shù)據(jù)到excel,csv
這篇文章主要介紹了pandas 如何保存數(shù)據(jù)到excel,csv的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07
python 實(shí)現(xiàn)在txt指定行追加文本的方法
下面小編就為大家分享一篇python 實(shí)現(xiàn)在txt指定行追加文本的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-04-04
使用Python的SymPy庫解決數(shù)學(xué)運(yùn)算問題的方法
這篇文章主要介紹了使用Python的SymPy庫解決數(shù)學(xué)運(yùn)算問題的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-03-03
利用Python實(shí)現(xiàn)自定義連點(diǎn)器
這篇文章主要介紹了如何利用Python實(shí)現(xiàn)自定義連點(diǎn)器,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08
Django框架中間件(Middleware)用法實(shí)例分析
這篇文章主要介紹了Django框架中間件(Middleware)用法,結(jié)合實(shí)例形式分析了Django框架中間件(Middleware)的功能、用法及相關(guān)操作技巧,需要的朋友可以參考下2019-05-05

