Django 基于channels实现群聊功能

后端框架
django
默认不支持 websocket
第三方模块: channels

flask
默认不支持 websocket
第三方模块: geventwebsocket

tornado
默认支持 websocket

下载 channel s模块需要注意的点

1 版本不要用最新版 推荐使用 2.3 版本即可,如果你安装最新版可能会出现自动将你本地的django 版本升级为最新版

2 python 解释器建议使用 3.6 版本(3.5 可能会有问题,3.7 可能会有问题 具体说明问题没有给解释)

pip3 install channles==2.3

channels 模块内部帮你封装了握手/加密/解密等所有操作

基本使用

  • 注册 app
INSTALLED_APPS = [
    'channels'
]

注册完成后,django 会无法启动,会直接报错

CommandError: You have not set ASGI_APPLICATION, which is needed to run the server.

  • 配置
ASGI_APPLICATION = 's13_day01.routing.application'
ASGI_APPLICATION = '项目名同名的文件名.文件夹下py文件名默认就叫routing.该py文件内部的变量名默认就叫application'
  • 去项目名同名的文件夹下面新建一个 routing.py 文件,定义 application 变量
from channels.routing import ProtocolTypeRouter,URLRouter
from django.conf.urls import url
from app01 import consumers

application = ProtocolTypeRouter({
    'websocket':URLRouter([
        # websocket相关的路由
        url(r'^chat/',consumers.ChatConsumer)
    ])
})

上述操作配置完成后,启动 django 会由原来的 wsgiref 启动变成 asgi 启动(内部:达芙妮)

并且启动之后 django 即支持 websocket 也支持 http 协议

基于 http 的操作还是在 urls.py 和 views.py 中完成

基于 websocket 的操作则在 routing.py 和 consumer.py (对应的应用中创建)中完成

from channels.generic.websocket import WebsocketConsumer


class ChatConsumer(WebsocketConsumer):
    def websocket_connect(self, message):
        """客户端请求建立链接时 自动触发"""
        pass


    def websocket_receive(self, message):
        """客户端发送数据过来  自动触发"""
        pass


    def websocket_disconnect(self, message):
        """客户端断开链接之后  自动触发"""
        pass
"""
http协议
	index路径		index视图函数
	访问:浏览器窗口直接输入的地址的

websocket协议
	chat路径		ChatConsumer视图类
	访问:new WebSocket对象访问
"""

方法总结

# 后端  3个
from channels.generic.websocket import WebsocketConsumer
from channels.exceptions import StopConsumer


consumer_object_list = []


class ChatConsumer(WebsocketConsumer):
    def websocket_connect(self, message):
        """客户端请求建立链接时 自动触发"""
        # print('请求链接')
        self.accept()  # 建立链接  并且自动帮你维护每一个客户端
        # 将链接在列表中存储一份
        consumer_object_list.append(self)


    def websocket_receive(self, message):
        """客户端发送数据过来  自动触发"""
        # print(message)  # message = {'type': 'websocket.receive', 'text': 'hello world!'}
        text = message.get('text')  # 真正的数据
        # 给客户端发送消息  单独发送
        # self.send(text_data=text)

        # 给所有的链接对象发送数据
        for obj in consumer_object_list:
            obj.send(text_data=text)


    def websocket_disconnect(self, message):
        """客户端断开链接之后  自动触发"""
        # print('断开链接')
        # 客户端断开链接之后 应该将当前对象移除
        consumer_object_list.remove(self)
        raise StopConsumer()



# 前端  4个
var ws = new WebSocket('ws://127.0.0.1:8000/chat/');

    // 1 握手环节验证成功之后 自动触发  onopen
    ws.onopen = function () {
        console.log('握手成功')
    }

    // 2 给服务端发送消息  send
    function sendMsg() {
        ws.send($('#txt').val())
    }

    // 3 一旦服务端有消息 自动触发  onmessage
    ws.onmessage = function (args) {
        // console.log(args)  // args是一个对象
        // 获取发送的数据
        console.log(args.data)
    }

    // 4 断开链接之后  自动触发  onclose
    ws.onclose = function () {
        ws.close()
    }

群聊功能

我们是通过自己维护一个列表存储链接对象的方式完成了简易版本的群聊

其实 channels 给你提供了一个用于做群聊的模块,该模块可以实现真正的分组聊天

 posted on 2020-04-14 15:32  Rannie`  阅读(1332)  评论(0编辑  收藏  举报
去除动画
找回动画