分享

django实现聊天室、消息推送

 看见就非常 2020-04-30
  • Django-channel可以做什么

在Django中,默认使用的是HTTP通信,不过这种通信方式有个很大的缺陷,就是不能很好的支持实时通信。如果硬是要使用HTTP做实时通信的话只能在客户端进行轮询了,不过这样做的开销太大了。

因此,在1.9版本之后,Django实现了对Channels的支持,他所使用的是WebSocket通信,解决了实时通信的问题,而且在使用WebSocket进行通信的同时依旧能够支持HTTP通信。

  • 实现结果

本项目实现了聊天室、消息推送。

  • 项目配置

  1. 搭建Django项目

不在讲述搭建项目步骤,以下是项目结构。

 

  1. Setting配置

INSTALLED_APPS中添加channels;

指定ASGI的路由地址,添加ASGI_APPLICATION = 'tbkt.routing.application'

设置消息通道,添加CHANNEL_LAYERS配置

  1. CHANNEL_LAYERS = {
  2. 'default': {
  3. 'BACKEND': 'channels_redis.core.RedisChannelLayer',
  4. 'CONFIG': {
  5. "hosts": ["redis://:password@address:port/db"],
  6. },
  7. },
  8. }
  1. Routing——websocket路由配置(类似于Django中的urls系统)

在setting同级目录下创建routing.py文件,文件内容如下:

  1. from channels.auth import AuthMiddlewareStack
  2. from channels.routing import ProtocolTypeRouter, URLRouter
  3. import apps.routing
  4. application = ProtocolTypeRouter({
  5. 'websocket': AuthMiddlewareStack(
  6. URLRouter(
  7. apps.routing.websocket_urlpatterns
  8. )
  9. ),
  10. })

ProtocolTypeRouter: ASIG支持多种不同的协议,在这里可以指定特定协议的路由信息,我们只使用了websocket协议,这里只配置websocket即可。

AuthMiddlewareStack: django的channels封装了django的auth模块,使用这个配置我们就可以在consumer中通过下边的代码获取到用户的信息。

具体的路由配置:

  1. from apps.chat.consumers import ChatConsumer
  2. from apps.message.consumers import MsgConsumer
  3. from django.conf.urls import url
  4. websocket_urlpatterns = [
  5. url('ws/chat/', ChatConsumer),
  6. url('ws/message/', MsgConsumer),
  7. ]

ChatConsumer 是处理请求的类方法。Websocket请求将有此类方法进行处理。

  1. 浏览器

浏览器发起websocket的请求,创建websocket对象支持四个消息:

onopen: 当浏览器和websocket服务端连接成功后会触发onopen消息。

onerror: 如果连接失败,或者发送、接收数据失败,或者数据处理出错都会触发onerror消息。

onmessage: 当浏览器接收到websocket服务器发送过来的数据时,就会触发onmessage消息,参数e包含了服务端发送过来的数据。

onclose: 当浏览器接收到websocket服务器发送过来的关闭连接请求时,会触发onclose消息。

  1. 服务器

创建一个房间名为Group name,所有的消息都会发送到这个Group里边,当然你也可以通过参数的方式将房间名传进来作为Group name,从而建立多个Group,这样可以实现仅同房间内的消息互通。

当我们启用了channel layer之后,所有与consumer之间的通信将会变成异步的,所以必须使用async_to_sync。

一个链接(channel)创建时,通过group_add将channel添加到Group中,链接关闭通过group_discard将channel从Group中剔除,收到消息时可以调用group_send方法将消息发送到Group,这个Group内所有的channel都可以收的到。

group_send中的type指定了消息处理的函数,这里会将消息转给chat_message函数去处理。

  • 知识点拓展

目前想到可以拓展的方向,

  1. 在发送消息通告时判断当前连接人数(即此时登录我们后台网站)。
  2. 为指定用户推送消息。
  3. 优化轮询,实时显示处理进度,减少资源。

 

代码地址:https://github.com/AIlvxiaobu/django_websocket.git

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多