詳解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文件夾用來(lái)存放HTML頁(yè)面:
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 文件同級(jí)目錄下新建 routing.py 文件,內(nèi)容如下:
from channels.routing import ProtocolTypeRouter
application = ProtocolTypeRouter({
# (http->django views is added by default)
})
把 channels 注冊(cè)在 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)建聊天頁(yè)面
創(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 中注冊(cè)路由
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端口啟動(dòng)redis : redis-server
在 settings.py 中添加如下配置:
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [('127.0.0.1', 6379)],
},
},
}
最后啟動(dòng)Django項(xiàng)目
使用多個(gè)瀏覽器打開(kāi)http://127.0.0.1:8000/chat/lobby/ ,開(kāi)始實(shí)時(shí)聊天吧。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Django實(shí)現(xiàn)WebSocket在線聊天室功能(channels庫(kù))
- 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)對(duì)點(diǎn)實(shí)時(shí)聊天和消息推送功能
- django使用channels2.x實(shí)現(xiàn)實(shí)時(shí)通訊
- django channels使用和配置及實(shí)現(xiàn)群聊
相關(guān)文章
Python cookbook(數(shù)據(jù)結(jié)構(gòu)與算法)在字典中將鍵映射到多個(gè)值上的方法
這篇文章主要介紹了Python在字典中將鍵映射到多個(gè)值上的方法,涉及Python針對(duì)字典的相關(guān)映射與初始化相關(guān)操作技巧,需要的朋友可以參考下2018-02-02
Python如何基于selenium實(shí)現(xiàn)自動(dòng)登錄博客園
這篇文章主要介紹了Python如何基于selenium實(shí)現(xiàn)自動(dòng)登錄博客園,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12
pygame游戲之旅 計(jì)算游戲中躲過(guò)的障礙數(shù)量
這篇文章主要為大家詳細(xì)介紹了pygame游戲之旅的第8篇,教大家實(shí)現(xiàn)游戲中躲過(guò)障礙數(shù)量的計(jì)算,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11
Django的數(shù)據(jù)模型訪問(wèn)多對(duì)多鍵值的方法
這篇文章主要介紹了Django的數(shù)據(jù)模型訪問(wèn)多對(duì)多鍵值的方法,Django是Python豐富多彩的web框架中最具人氣的一個(gè),需要的朋友可以參考下2015-07-07
mac安裝scrapy并創(chuàng)建項(xiàng)目的實(shí)例講解
今天小編就為大家分享一篇mac安裝scrapy并創(chuàng)建項(xiàng)目的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-06-06
python按綜合、銷量排序抓取100頁(yè)的淘寶商品列表信息
這篇文章主要為大家詳細(xì)介紹了python按綜合、銷量排序抓取100頁(yè)的淘寶商品列表信息,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-02-02

