博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Django channels
阅读量:6037 次
发布时间:2019-06-20

本文共 1937 字,大约阅读时间需要 6 分钟。

hot3.png

      最近完成的一个项目用到了websock+channels实现实时通讯,这里把自己的心得写下来分享分享,希望可以对有这方面的需求的朋友有所帮助。

       channels是django1.9以后才出的一个新的特性,它允许Django以“通道模式”运行,通过建立通道层,来向消费者和生产者(消息发送者)之间传递消息。

        安装channels:pip install channels

        安装channels所依赖的通道层(一般都是redis,也可以是别的):pip install asgi_redis

        在Django项目中配置channnels:

        1.在settings文件的INSTALLED_APPS里面加入channels

          INSTALLED_APPS = [

               . . .

                'channels',

          ]

         2.在settings文件中加入channels通道层的配置:

CHANNEL_LAYERS = {

    "default": {
        "BACKEND": "asgi_redis.RedisChannelLayer",
        "CONFIG": {
            "hosts":[("localhost", 6379)], 
        },
        "ROUTING": "testchannels.routing.routing",
    },
}

      解释一下这段代码:它跟DATABASES的配置有点像,BACKEND指定channels通道层由redis实现。CONFIG是IP跟redis端口。ROUTING又叫通道路由,通道路由将通道映射到消费者函数。跟 urls.py类似,当有WebSocket请求访问时,就会根据这个路径找到相应表单,调用相应的函数进行处理,按照惯例通道路由应该在routing.py里。

       3.替换掉Django的基于HTTP/WSGI的请求处理器,而是使用通道。它是一个基于新兴标准ASGI(异步服务器网关接口)的, 所以我们将在asgi.py文件里定义处理器:

134906_4lbf_3420568.png

       上面的都配置完以后就可以开始写代码了。

       主要要创建2个文件——consumer.py,routing.py

       routing.py:

      140347_ZyWe_3420568.png

当websocket建立连接时,会寻找websocket.connet,然后调用noGroupConsumer.ws_connect方法。 

当websocket发送数据时,会寻找websocket.receive,然后调用noGroupConsumer.ws_receive方法。

 当websocket断开连接时,会寻找websocket.disconnect,然后调用noGroupConsumer.ws_disconnect方法。

然后创建我的consumer文件noGroupConsumer.py:

     141340_vcGI_3420568.png

每行代码什么意思都标注清楚了,这里就不做解释了。

测试:运行项目,然后创建一个websocket连接发送消息。

142107_BDUC_3420568.png

连接websocket然后发送一个“hello world”,这时会弹一个框 hello world说明channels成功。

注意图上画红圈的url跟routing里面的对照一下。

Group

      上面只是最基本的websocket+channels知识。如果有很多的websocket连接,但是他们需要收到不同的消息,怎么处理呢?就比如A集合跟B集合两个websocket连接集合。A集合中的任何一个元素发了一条信息,所有元素都能收到,但是B集合根本不想收到A集合中元素发的信息,怎么办呢?channels中的Group就是解决这个问题的——把信息发送到它需要的地方。

routing.py:

143110_YaDK_3420568.png

consumer:groupConsumer.py:

143808_FxUR_3420568.png

        当建立连接后,把连接存入到Group中:Group("myRoom").add(message.reply_channel)

myRoom是Group的名字。Group("myRoom").send({"text":data})就会把数据发送到加入到myRoom里面的连接。

我们可以改一下上面那个html代码

144356_Bzbm_3420568.png

跟之前唯一不同的就是websocket url需要加上组名(Group 的name)

Ok,这样通过Group编码也完成了,但是Group名是不能变的,如何动态的连接到各个Group呢?

其实可以从message['path']里面提取出Group的名字,然后把myRoom替换掉就行

代码GitHub地址:https://github.com/shichaosc/gitskills/tree/master/jozzon

转载于:https://my.oschina.net/u/3420568/blog/1555452

你可能感兴趣的文章
python3的print函数
查看>>
django from表单验证
查看>>
PS 不能使用移动工具 因为目标图层被隐藏怎么办
查看>>
Intellij实用技巧
查看>>
linux sed命令详解
查看>>
nexus 手动更改 私服包
查看>>
BZOJ 2406: 矩阵 [上下界网络流 二分答案]
查看>>
Android的读写文件及权限设置
查看>>
编程之美2.12 高速寻找满足条件的两个数
查看>>
数据结构之---C语言实现线索二叉树
查看>>
THP Transparent HugePages 相关知识与关闭【转】
查看>>
Struts2的输入校验
查看>>
(第6篇)大数据发展背后的强力推手——HBase分布式存储系统
查看>>
string的内存管理问题
查看>>
日文符号“・”插入sql-server2005乱码问题
查看>>
Fragment 重叠 遮盖问题
查看>>
iOSGCD的使用以及死锁的问题
查看>>
RTB 广告系统
查看>>
Linux signal 那些事儿(2)【转】
查看>>
InfluxDB安装及配置
查看>>