0


django websocket

Django实现支持websocket协议

websocket的简单介绍可参考博主之前的博文websocket,本片通过测试示例代码介绍一下Django实现支持websocket协议

django默认wsgi不支持websocket协议,只支持http协议。而asgi(daphne)既支持http也支持websocket协议。所以想让django支持则需安装第三方组件,如下:

pip install channels -i https://mirrors.aliyun.com/pypi/simple/

daphne介绍参考链接:

channels介绍参考链接:

django示例项目配置

本次示例代码目录结构如下图:

avatar

  1. settings.py文件配置
# 注册channels
INSTALLED_APPS =['channels','django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','corsheaders','apps.test01','apps.chat']# 添加asgi application的配置
ASGI_APPLICATION ="my_web01.routing.application"# 方式二, 本人采用此方式# ASGI_APPLICATION = "my_web01.asgi.application" # 方式一,默认# 以下配置为channel_layer内容,请参考channels参考链接其中有实现群聊的代码# 因为实现群聊所以用到channel_layer,如果实现简单的功能以下配置可以暂时不用#信道层是一种通信系统。它允许多个消费者实例彼此交谈,以及与Django的其他部分交谈。#通道层提供以下抽象:#通道是一个可以将邮件发送到的邮箱。每个频道都有一个名称。任何拥有频道名称的人都可以向频道发送消息。#一组是一组相关的通道。一个组有一个名称。任何具有组名称的人都可以按名称向组添加/删除频道,并向组中的所有频道发送消息。无法枚举特定组中的通道。#每个使用者实例都有一个自动生成的唯一通道名,因此可以通过通道层进行通信。
CCHANNEL_LAYERS ={'default':{'BACKEND':'channels_redis.core.RedisChannelLayer','CONFIG':{#"hosts": [('127.0.0.1', 6379)],# "hosts": ["redis://127.0.0.1/14"],# 此处的IP为redis是因为使用容器编排创建redis容器时指定 links:- redis# 即redis与IP创建了对应关系"hosts":["redis://:123456@redis:6379/14"],# "hosts": [("redis",6379)],},# "CONFIG": {#     "hosts": ["redis://:password@IP:6379/0"],#     "symmetric_encryption_keys": [SECRET_KEY],# },},}
  • 解释说明:​ 特别是对于大型站点,可以配置像 nginx 这样的生产级 HTTP 服务器, 以根据路径将请求路由到(1)用于普通 HTTP 请求的生产级 WSGI 服务器(如 Gunicorn+Django) 或(2)生产- 级 ASGI 服务器,例如用于 WebSocket 请求的 Daphne+Channels。​ 请注意,对于较小的站点,可以使用更简单的部署策略(asgi包含http与websocket服务) 其中 Daphne 服务所有请求 - HTTP 和 WebSocket - 而不是拥有单独的 WSGI 服务器。
  1. asgi.py文件配置(与wsgi同级目录,没有则新建asgi文件)
# 方式二(目的只实现websocket的长连接,所有的http请求还是走wsgi)import os
import django
from channels.routing import get_default_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE','my_web01.settings')
django.setup()
application = get_default_application()# 方式一(既包含http又包含websocket)# import os# from channels.auth import AuthMiddlewareStack# from channels.routing import ProtocolTypeRouter, URLRouter# from channels.security.websocket import AllowedHostsOriginValidator# from django.core.asgi import get_asgi_application# os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_web01.settings")# django_asgi_app = get_asgi_application()## from apps.chat import routing## application = ProtocolTypeRouter({#   "http": django_asgi_app,#   "websocket": AllowedHostsOriginValidator(#         AuthMiddlewareStack(#             URLRouter(#                 routing.websocket_urlpatterns#             )#         )#     ),# })

3.routing.py文件配置(与asgi文件同级目录下新建即在settings文件中的配置的文件位置)

from channels.routing import ProtocolTypeRouter
from apps.chat import routing
application = ProtocolTypeRouter({'websocket': routing.websocket_urlpatterns
})

4.apps/chat/routing.py文件

# routing文件效果等同于urls.py文件from django.urls import re_path
from channels.routing import URLRouter
from.import consumers

# 我们调用as_asgi()classmethod 是为了获得一个 ASGI 应用程序,# 该应用程序将为每个用户连接实例化我们的消费者实例。这类似于 Django 的as_view(),# 它对每个请求的 Django 视图实例扮演相同的角色。# 本示例未使用as_asgi()因为django版本为低版本

websocket_urlpatterns = URLRouter([# 所有websocket以ws/开始是约定俗成的
    re_path(r'ws/chat/(?P<room_name>\w+)/$', consumers.ChatConsumer),])

5.apps/chat/consumers.py文件

# 简单示例代码# consumers文件效果等同于views.py文件import json
from channels.generic.websocket import WebsocketConsumer

classChatConsumer(WebsocketConsumer):def__init__(self,*args,**kwargs):super(ChatConsumer, self).__init__(*args,**kwargs)
        self.room_name =''
        self.room_group_name =''defconnect(self):# 获取传参参数或者header内容则通过self.scopeprint('websocket连接的参数内容:', self.scope)
        self.room_name = self.scope['url_route']['kwargs']['room_name']
        self.room_group_name ='chat_%s'% self.room_name
        self.accept()defdisconnect(self, close_code):
        self.close()# 断开连接defreceive(self, text_data=None, bytes_data=None):
        data = text_data or bytes_data
        if data:
            data = json.loads(data)print('接收到的参数:', data)
            msg = data.get('msg')if msg =='ok':
                self.send(json.dumps({'content':'收到了ok'}))else:
                self.send(json.dumps({'content':f'收到了{msg}'}))

以上就是简单的demo;python manage.py runserver之后出现如下图“ASGI/Channels”则表明集成了channels支持http和

websocket(长连接)协议了。

avatar

使用postman测试长连接请求

1.打开postman点击左上角"New",按照下图所选

2.postman测试连接,并发送消息如下图:

文档最后,当然关于websocket的技术知识点还有很多,本文只是快速简单了解其过程。相信通过简单的测试,对django支持长连接有所了解,如果深入的了解请访问文章开始博主分享的官网地址。

分享他人github 简单示例

https://github.com/py3study/django3_websocket

标签: django websocket python

本文转载自: https://blog.csdn.net/weixin_45172107/article/details/126590769
版权归原作者 穿过那片麦田 所有, 如有侵权,请联系我们删除。

“django websocket”的评论:

还没有评论