带你进入异步Django+Vue的世界 - Didi打车实战(4)

上一篇: 带你进入异步Django+Vue的世界 - Didi打车实战(3)
后台数据模型设计
Demo: https://didi-taxi.herokuapp.com/

Django Channels

为了支持即时消息收发、群发群收、异步处理,我们对后台添加Channels。

  • WebSockets
  • Django Channels
  1. 安装Channels:
    pip install channels channels-redis

  2. 修改配置文件:

  • 添加channels APP
  • 添加ASGI_APPLICATION
  • 添加CHANNEL_LAYERS,使用Redis作为后台
# /backend/settings/dev.py
INSTALLED_APPS = [
    'channels',
。。。

ASGI_APPLICATION = 'backend.routing.application'

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'dist', 'media')

REDIS_URL = os.getenv('REDIS_URL', 'redis://localhost:6379')

CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': { 'hosts': [REDIS_URL]},
    }
}
  1. 创建ASGI application
    运行django时,会切换到ASGI服务模式,同时处理HTTP和Websockets访问。
# /backend/asgi.py
import os

import django

from channels.routing import get_default_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'backend.settings.dev')
django.setup()
application = get_default_application()
  1. 创建ASGI路由文件
    前端以/ws/taxi/地址来进行WebSockets请求。
# backend/routing.py

from django.urls import path 
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter

from .api.consumers import TaxiConsumer

# changed
application = ProtocolTypeRouter({
    'websocket': AuthMiddlewareStack(
        URLRouter([
            path('ws/taxi/', TaxiConsumer),
        ])
    )
})
  1. 创建Consumer
    Consumer是实现类似View的功能,处理WebSockets消息。
# api/consumers.py

from channels.generic.websocket import AsyncJsonWebsocketConsumer

class TaxiConsumer(AsyncJsonWebsocketConsumer):

    async def connect(self):
        user = self.scope['user']
        if user.is_anonymous:
            await self.close()
        else:
            await self.accept()
            content = {
              'type': 'from Django',
              'data': "welcome, you're connected to Channels!"
            }
          await self.send_json(content)

拒绝非登录用户。对于已登录用户,则接收连接,并返回欢迎信息。

目录改动不少,当前结构为:

git/didi-project$ tree -I node_modules -L 3
.
├── LICENSE
├── Pipfile
├── Pipfile.lock
├── Procfile
├── README.md
├── app.json
├── backend
│   ├── __init__.py
│   ├── api
│   │   ├── __init__.py
│   │   ├── admin.py
│   │   ├── apps.py
│   │   ├── consumers.py
│   │   ├── migrations
│   │   ├── models.py
│   │   ├── serializers.py
│   │   ├── tests.py
│   │   ├── urls.py
│   │   └── views.py
│   ├── asgi.py
│   ├── routing.py
│   ├── settings
│   │   ├── __init__.py
│   │   ├── dev.py
│   │   └── prod.py
│   ├── urls.py
│   └── wsgi.py
├── db.sqlite3
├── dist
├── manage.py
├── package.json
├── public
│   ├── index.html
│   ├── manifest.json
│   ├── robots.txt
│   └── static
│       ├── favicon.ico
│       └── img
├── src
│   ├── App.vue
│   ├── assets
│   ├── components
│   ├── config.js
│   ├── main.js
│   ├── plugins
│   │   └── vuetify.js
│   ├── registerServiceWorker.js
│   ├── router.js
│   ├── services
│   │   ├── api.js
│   │   └── messageService.js
│   ├── store
│   │   ├── index.js
│   │   └── modules
│   │   │   └── messages.js
│   └── views
│       ├── Home.vue
│       ├── My404.vue
│       ├── Signin.vue
│       └── Signup.vue
├── vue.config.js
└── yarn.lock

运行ASGI

启动Redis服务:redis-server&
运行Django: python manage.py runserver

看到如下提示,就说明ASGI服务成功启动了:

(didi-project) git/didi-project$ python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
May 19, 2019 - 07:28:17
Django version 2.2.1, using settings 'backend.settings.dev'
Starting ASGI/Channels version 2.2.0 development server at http://127.0.0.1:8000/

验证一下,之前的HTTP登录、注册等功能一切正常。

前端添加WebSockets支持

直接写到

你可能感兴趣的:(带你进入异步Django+Vue的世界 - Didi打车实战(4))