IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> Django插件Channels ——实现即时通信 -> 正文阅读

[Python知识库]Django插件Channels ——实现即时通信

注明

本笔记主要参考《Django应用开发实战》《Django企业开发实战》,这两本书前者详细,后者精炼。学习之后真的是感觉自己进步了很多。值得一读,如果您遇到了值得一读的书籍,欢迎推荐给我,大家共同进步。


@[TOC](文章目录)

前言

Web聊天室的实现方法有多种,下面将简要介绍一下实现方法

  • AJAX技术利用AJAX实现网页与服务器的无刷新交互。缺点是实时性不高。
  • Coment技术Coment是一种Web应用框架,服务器以异步方式向浏览器推送数据,无需浏览器发送请求,非常适合事件驱动的Web应用,以及对交互性和实时性要求较高的应用。
  • XMPP协议:可扩展消息处理协议,专为及时通信系统设计的通信协议,用于即时消息以及在线探测
  • Flash的XmlSocket:Flash Media Server 是一个强大的流媒体服务器,它基于RTMP协议,提供了稳定的流媒体交互功能,内置远程共享对象的机制,是浏览器创建并连接服务器的远程共享
  • websocket协议:WebSocket是一种在单个TCP连接上进行全双工通信的协议WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket
    API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输

django实现websocket大致上有两种方式,一种channels,一种是dwebsocket。channels依赖于redis,twisted等


提示:以下是本篇文章正文内容,下面案例可供参考

一、Channels?

Channels安装与配置

pip install channels
pip channels_redis
pip install pypiwin32

settings配置

INSTALLED_APPS = [
'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'channels', # 添加channels功能
    'chat',
]
ASGI_APPLICATION = '项目名.routing.application'
CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': {
            "hosts": [('127.0.0.1', 6379)],
        },
    },
}

说明:

  • CHANNEL_LAYERS用于设置Redis数据库的连接方式.
  • ASGI_APPLICATION:代表routing.py定义的application对象。

项目名文件夹下定义routing.py

from channels.routing import ProtocolTypeRouter
from channels.routing import URLRouter
from .urls import websocket_urlpatterns

application = ProtocolTypeRouter({
    # (http->django views is added by default)
    'websocket': AuthMiddlewareStack(
        URLRouter(
            websocket_urlpatterns
        )
    ),
})

说明:

定义这个文件是为了响应ASGI_APPLICATION定义application对象,将Django与该插件建立连接。

在项目名文件夹下urls.py,定义websocket_urlpatterns

from django.urls import path, include
from .consumers import ChatConsumer
urlpatterns = [
    path('', include(('chat.urls', 'chat'), namespace='chat'))
]

websocket_urlpatterns = [
    path('ws/chat/<room_name>/', ChatConsumer),
]

说明:

  • websocket_urlpatterns用于定义Channels的路由信息,上数定义的路由ws/chat/<room_name>/,它是由consumers.py的ChatConsumer处理和响应HTTP请求的,该路由作为Channels的API接口由网页的Javascript与该路由构建通信连接,使浏览器和服务器之间相互传递数据。

最后定义consumers.py

# from asgiref.sync import async_to_sync
# from channels.generic.websocket import WebsocketConsumer
# import json
#
# # 将消费者代码为同步。
# class ChatConsumer(WebsocketConsumer):
#     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
#         async_to_sync(self.channel_layer.group_add)(
#             self.room_group_name,
#             self.channel_name
#         )
#
#         self.accept()
#
#     def disconnect(self, close_code):
#         # Leave room group
#         async_to_sync(self.channel_layer.group_discard)(
#             self.room_group_name,
#             self.channel_name
#         )
#
#     # Receive message from WebSocket
#     def receive(self, text_data):
#         text_data_json = json.loads(text_data)
#         message = text_data_json['message']
#
#         # Send message to room group
#         async_to_sync(self.channel_layer.group_send)(
#             self.room_group_name,
#             {
#                 'type': 'chat_message',
#                 'message': message
#             }
#         )
#
#     # Receive message from room group
#     def chat_message(self, event):
#         message = event['message']
#
#         # Send message to WebSocket
#         self.send(text_data=json.dumps({
#             'message': message
#         }))


#-------------low------------
# 将消费者代码重写为异步,以提高其性能。
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
        }))

下面可以很简单的实现在线聊天功能

大致思路:在应用urls中设置两个路由:创建聊天和进入聊天室。在创建聊天室后即跳转到进入聊天室路由。进入聊天室路由网页设置:使网页与项目插件连接,设置接收和发送信息(也可以设置异常事件触发器)。下面步骤

chat urls

from django.urls import path
from .views import *

urlpatterns = [
    # 用于开启新的聊天室
    path('', newChat, name='newChat'),
    # 创建聊天室
    path('<room_name>/', room, name='room'),
]
chat views
from django.shortcuts import render
# 用于创建或进入聊天室
def newChat(request):
    return render(request, 'chat.html', locals())

# 创建聊天室
def room(request, room_name):
    return render(request, 'room.html', locals())
chat.html(截取部分重要)
<body>
    <div>请输入聊天室名称</div>
   <br/>
    <input id="input" type="text" size="30"/>
   <br/>
    <input id="submit" type="button" value="进 入"/>

    <script>
        document.querySelector('#input').focus();
        document.querySelector('#input').onkeyup = function(e) {
            if (e.keyCode === 13) {  // enter, return
                document.querySelector('#submit').click();
            }
        };

        document.querySelector('#submit').onclick = function(e) {
            var roomName = document.querySelector('#input').value;
            window.location.pathname = '/' + roomName + '/';
        };
    </script>
</body>
说明:
确定聊天室名称后,单击进入或者回车将触发javaScript脚本。

room.html

<body>
    <textarea id="chat-log" cols="50" rows="6"></textarea>
    <br/>
    <input id="input" type="text" size="50"/><br/>
    <input id="submit" type="button" value="发 送"/>
</body>
<script>
    var roomName = '{{ room_name }}';

    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('#input').focus();
    document.querySelector('#input').onkeyup = function(e) {
        if (e.keyCode === 13) {  // enter, return
            document.querySelector('#submit').click();
        }
    };

    document.querySelector('#submit').onclick = function(e) {
        var messageInputDom = document.querySelector('#input');
        var message = messageInputDom.value;
        chatSocket.send(JSON.stringify({
            'message': message
        }));

        messageInputDom.value = '';
    };
</script>
说明:
	var chatSocket部分为了网页与项目插件连接
	chatSocket.onmessage接收数据,并展示到文本框
	chatSocket.onclose关闭连接,当出现异常时触发
	document.querySelector发送数据
	querySelector将文本展示到网页textarea组件中。
  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-09-07 10:46:22  更:2021-09-07 10:48:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 13:52:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码