django基于channels实现群聊功能

"""
补充
我们用pycharm创建的django项目会自动帮你创建templates文件夹并且是全局的

其实除了可以在全局创建模版文件夹之外,还可以做到更加的细化 就是在每一个应用下创templates模版文件夹

如果出现多个应用和全局都有模版文件夹的情况,那么会优先查找全局
如果全局没有,则按照配置文件中注册app的顺序的从上往下一次查找每一个应用下templates
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01.apps.App01Config',
]

每一个应用都可以有自己的urls.py(路由分发),views.py,templates,static
"""

配置完成后同时支持http和websocket的原因(源码)

class ProtocolTypeRouter:
    """
    Takes a mapping of protocol type names to other Application instances,
    and dispatches to the right one based on protocol name (or raises an error)
    """
    def __init__(self, application_mapping):
        self.application_mapping = application_mapping
        if "http" not in self.application_mapping:
            self.application_mapping["http"] = AsgiHandler

前期三步配置完成后继续书写以下代码

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)
    ])
})
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个
class ChatConsumer(WebsocketConsumer):
    def websocket_connect(self, message):
        """客户端请求建立链接时 自动触发"""
        self.accept()  # 建立链接  并且自动帮你维护每一个客户端

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


    def websocket_disconnect(self, message):
        """客户端断开链接之后  自动触发"""
        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给你提供了一个用于做群聊的模块,该模块可以实现真正的分组聊天

该模块就是channel-layers

Only you can control your future You're not alone. You still have family,peopel who care for you and want to save you.