Django channels

      最近完成的一个项目用到了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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值