最近,我必须为一家创业公司构建REST API,在此期间,我的任务是为其聊天应用程序构建Web插座。我认为这是一项简单的工作,因为我过去做过类似的事情,但是后来我意识到我以前从未托管过Web插座项目。
通过大量文档,我开始使用达芙妮(Daphne)的部署过程,但这是徒劳的。 http
和websocket
端点都无法正常工作。经过大量的研究和文档阅读,我能够运行它。在本教程中,我将为如何在铁路上托管您的Django Asgi项目提供详细的解释。
我会假设您已经对Django和Django频道知识很少,因此我不会对此做出很多解释。让我们首先创建我们的Django项目
$ mkdir chat
$ cd chat
$ python -m venv venv
$ source venv/bin/activate
$ pip install django channels_redis
$ django-admin startproject chat .
$ python manage.py startapp myapp
将在当前目录中创建App myapp
。转到chat/settings.py
并将myapp
添加到INSTALLED_APPS
# chat/settings.py
INSTALLED_APPS = [
# other apps
"myapp.apps.MyappConfig",
]
接下来,在终端运行以下命令。
$ python manage.py migrate
$ python manage.py createsuperuser
运行上述命令后,请确保启动服务器,以确保您的项目通过下面的命令运行
$ python manage.py runserver
访问https://localhost:8000/查看该项目。接下来,我们将配置我们的项目以使用 asgi 。要使用ASGI服务器,我们将安装django-channels
和daphne
。
$ python -m pip install channels["daphne"]
安装完成后,将以下代码添加到必要的文件中。
# chat/settings py
INSTALLED_APPS = [
"daphne" # this should be the topmost app.
# other apps
]
ASGI_APPLICATION = "chat.asgi.application"
# chat/asgi.py
import os
from django.core.asgi import get_asgi_application
import django
# django channels
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.security.websocket import AllowedHostsOriginValidator
from chat.websocket_urls import websocket_urlpatterns
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Chat.settings')
django.setup()
application = ProtocolTypeRouter({
"http": get_asgi_application(),
"websocket": AllowedHostsOriginValidator(
AuthMiddlewareStack(
URLRouter(
websocket_urlpatterns
)
)
)
})
现在,我们的设置部分完成了,请返回终端并重新启动服务器。您应该看到这样的东西。如果看起来不那样,请尝试进行故障排除。
另一种可以运行服务器的方式是直接使用Daphne。
$ daphne chat.asgi: application
为了加快事物的速度,我将为消费者和路由器提供代码。快速在myapp
目录中创建两个文件。文件应命名为cumput.py and Routers.py。将以下代码添加到文件中。
# myapp/consumers.py
import json
from channels.generic.websocket import AsyncWebsocketConsumer
class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
await self.accept()
# other code
async def disconnect(self, close_code):
await self.channel_layer.group_discard(self.room_group_name, self.channel_name)
async def receive(self, text_data):
# piece of code to handle receive events.
# myapp/routers.py
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r"ws/chat/(?P<room_name>\w+)/$",consumers.ChatConsumer.as_asgi()),
]
尚未完成,因为我们仍然需要使用频道层来广播消息。为此,将此代码添加到chat/settings py
。
# chat/settings.py
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [("localhost", 6379)],
},
},
}
我们现在已经设置了频道层,现在可以通过消息广播。到目前为止,我们一直在开发环境,现在就部署我们的应用程序。生产环境与开发环境完全不同,但由于我从一开始就已经想到了,因此无需改变。
$ python -m pip install psycopg2 gunicorn uvicorn
$ pip freeze > requirements.txt
安装了这些软件包并创建requirements.txt
文件后,创建一个文件并将其命名为Procfile
,而没有扩展名。这告诉铁路部署我们的应用程序时要使用的开始命令。将其添加到文件中。
web: python manage.py migrate && python -m gunicorn Chat.asgi:application -k uvicorn.workers.UvicornWorker
需要对我们的chat/settings.py
文件进行一些更改,但我只会介绍其中的一些。
# chat/settings.py
import os
SECRET_KEY = os.environ.get("SECRET_KEY")
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": os.environ.get("PG_NAME"),
"USER": os.environ.get("PG_USER"),
"PASSWORD": os.environ.get("PG_PASSWORD"),
"HOST": os.environ.get("PG_HOST"),
"PORT": os.environ.get("PG_PORT"),
}
}
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [(os.environ.get("REDIS_URL"))], # update this line.
},
},
}
通过这几个更改,我们准备将渠道申请部署到铁路。转到铁路网站,创建一个PostgreSQL项目和Redis项目。完成后,通过从GitHub中选择该项目来创建一个Django项目(您现在应该推出代码)。转到变量,并设置我们在settings.py
中使用的所有环境变量和项目中的其他变量。 PostgreSQL的环境变量在您创建的PostgreSQL项目中,对于Redis环境变量相同。另外,您很可能应该将DJANGO_SETTINGS_MODULE
变量设置为项目的settings.py
文件。完成此操作后,您的项目现在应该进行。
如果您在部署期间遇到的任何问题,请在评论部分中指出,我很乐意为您提供帮助