我一直在玩Django频道一段时间,我一直坚持如何让它在本地开发服务器设置之外工作。在有人向我发贴文档页面之前,我已经用尽了搜索Django Channels文档以及我能找到的其他任何地方。我可以让本地设置工作正常,但不是外部。多年来我一直坚持使用Django开发服务器的理念,无论如何都是因为这种情况。
所以这是:
我有一个django网站,多年来一直由apache服务并使用LDAP用户身份验证(这个问题超出了我的控制范围并且支付等级)。我已经安装了Django频道asgi_redis
,redis-server
,接口服务器Daphne自动安装了Django频道。我也在CentOS 6/7工作。
到目前为止,我已经知道我需要使用apache作为反向代理来与ASGI / Daphne交谈,但显然我找不到我需要的信息或自己弄明白。
这是我能想到的最接近的配置。我将我的apache配置文件设置为(URL是外部的,因为我的开发服务器是远程的;敏感信息当然是编辑的):
< VirtualHost *:80 >
# Django Channels
ProxyPass "/ws/" "ws://192.168.xx.xx/"
ProxyPassReverse "/ws/" "ws://192.168.xx.xx/"
ProxyPass "/" "http://192.168.xx.xx/"
ProxyPassReverse "/" "http://192.168.xx.xx/"
WSGIDaemonProcess dashboard_jnett python-path=/home/jnett/dashboard_jnett:/home/jnett/airview_env/lib/python2.7/site-packages
WSGIScriptAlias /dashboard_jnett /home/jnett/dashboard_jnett/apache/dashboard_jnett.wsgi process-group=dashboard_jnett
<Directory /home/jnett/dashboard_jnett>
AuthType Basic
AuthName "Web Utilities"
AuthBasicProvider ldap
AuthGroupFile /dev/null
require valid-user
AuthLDAPBindDN "uid=authenticate,ou=system,dc=intranet,dc=row44,dc=com"
AuthLDAPBindPassword "xxxxxxx"
AuthLDAPURL ldap://192.168.xx.xx/ou=users,dc=intranet,dc=row44,dc=com?cn??(&(objectclass=inetOrgPerson)(member=cn=status))
Require ldap-filter objectClass=inetOrgPerson
</Directory>
Alias /static/dashboard_jnett /var/www/html/static/dashboard_jnett
<Directory /var/www/html/static/dashboard_jnett>
AllowOverride None
Require all granted
Options FollowSymLinks
</Directory>
</VirtualHost>
我通过以下网址访问浏览器中的网站:http://192.168.xx.xx/dashboard_jnett/
在我的项目代码中,我有asgi.py
文件:
进口口
import channels.asgi
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings_jnett")
channel_layer = channels.asgi.get_channel_layer()
在ASGI文件中的那个设置文件settings_jnett.py
引用中,我有:
import asgi_redis
...
CHANNEL_LAYERS = {
"default": {
"BACKEND": "asgi_redis.RedisChannelLayer",
"CONFIG": {
"hosts": [os.environ.get('REDIS_URL', 'redis://192.168.xx.xx:6379')],
"prefix": u"dashboard_jnett",
},
"ROUTING": "routing.channel_routing",
},
}
以及添加到INSTALLED_APPS
的相应软件包,我遗漏了这些软件包。
这确实指向routing.py
文件,其中包含:
from channels.routing import route
from channeltest.consumers import ws_connect, ws_message, ws_disconnect, http_consumer
channel_routing = [
route("websocket.connect", ws_connect),
route("websocket.receive", ws_message),
route("websocket.disconnect", ws_disconnect),
route("http.request", consumers.http_consumer),
#route("websocket.receive", "consumers.ws_message"),
]
从此consumers.py
文件
from django.http import HttpResponse
from channels.handler import AsgiHandler
from channels import Group
from channels.sessions import channel_session
# Connected to websocket.connect
@channel_session
def ws_connect(message):
# Accept connection
message.reply_channel.send({"accept": True})
# Work out room name from path (ignore slashes)
room = message.content['path'].strip("/")
# Save room in session and add us to the group
message.channel_session['room'] = room
Group("chat-%s" % room).add(message.reply_channel)
# Connected to websocket.receive
@channel_session
def ws_message(message):
Group("chat-%s" % message.channel_session['room']).send({
"text": message['text'],
})
# Connected to websocket.disconnect
@channel_session
def ws_disconnect(message):
Group("chat-%s" % message.channel_session['room']).discard(message.reply_channel)
def http_consumer(message):
response = HttpResponse("Hello world! You asked for %s" % message.content['path'])
for chunk in AsgiHandler.encode_response(response):
message.reply_channel.send(chunk)
我让Daphne在终端中运行:
[jnett@dev03.nlv ~/dashboard_jnett ]$(airview_env)[jnett@dev03.nlv ~/dashboard_jnett ]$daphne -b 192.168.xx.xx asgi:channel_layer --port 6379
2017-08-23 18:57:56,147 INFO Starting server at tcp:port=6379:interface=192.168.xx.xx, channel layer asgi:channel_layer.
2017-08-23 18:57:56,147 INFO HTTP/2 support not enabled (install the http2 and tls Twisted extras)
2017-08-23 18:57:56,147 INFO Using busy-loop synchronous mode on channel layer
2017-08-23 18:57:56,148 INFO Listening on endpoint tcp:port=6379:interface=192.168.xx.xx
2017-08-23 18:57:56,148 INFO HTTPFactory starting on 6379
2017-08-23 18:57:56,148 INFO Starting factory <daphne.http_protocol.HTTPFactory instance at 0x54aca28>
我在另一个终端运行:
[jnett@dev03.nlv ~/dashboard_jnett ]$python manage.py runworker
2017-06-14 20:46:47,988 - INFO - runworker - Using single-threaded worker.
2017-06-14 20:46:47,988 - INFO - runworker - Running worker against channel layer default (asgi_redis.core.RedisChannelLayer)
2017-06-14 20:46:47,989 - INFO - worker - Listening on channels http.request, websocket.connect, websocket.disconnect, websocket.receive
我的redis服务器在另一个终端上运行:
[jnett@dev03.nlv ~/dashboard_jnett ]$~jnett/redis-stable/src/redis-server
...
10940:M 14 Jun 20:41:25.224 * The server is now ready to accept connections on port 6379
我甚至没有尝试使用网络套接字 - 我只是尝试提供正常的HTTP流量,但我似乎只能从apache获取代理错误:
代理错误
代理服务器收到来自上游服务器的无效响应。 代理服务器无法处理请求GET / dashboard_jnett / channeltest /.
原因:从远程服务器读取错误
apache错误日志给了我很多行,比如
[Wed Jun 14 21:39:52.718388 2017] [proxy_http:error] [pid 13123] (70007)指定的超时已过期:[client 192.168.xx.xx:51814] AH01102:从远程服务器192.168.xx.xx:80读取状态行的错误 [Wed Jun 14 21:39:52.718426 2017] [代理:错误] [pid 13123] [客户 192.168.xx.xx:51814] AH00898:从/ dashboard_jnett / channeltest /
返回的远程服务器读取时出错
有没有人成功将这样的设置投入生产?我希望如果我能弄明白如何让apache正确地将流量引导到Daphne以获得正常的HTTP,我可以从那里找到我的方式。
答案 0 :(得分:0)
我也很难使它在我的Raspberry上运行,但最终我做到了。
来自https://mikesmithers.wordpress.com/2017/02/21/configuring-django-with-apache-on-a-raspberry-pi/ 我有很好的建议。
Apache需要一些其他软件包来提供Django应用程序中的页面。
sudo apt-get install apache2-dev
sudo apt-get install libapache2-mod-wsgi-py3
还必须设置MPM(多处理模块)。
a2dismod mpm_prefork
a2enmod mpm_worker
service apache2 restart
从Django渠道文档中创建asgi.py示例
https://channels.readthedocs.io/en/latest/deploying.html#run-protocol-servers
就我而言,我还必须将sys路径添加到我的项目中
"""
ASGI entrypoint. Configures Django and then runs the
application
defined in the ASGI_APPLICATION setting.
"""
import os
import sys
import django
from channels.routing import get_default_application
sys.path.append("/home/pi/Dev/WeatherStation")
os.environ.setdefault("DJANGO_SETTINGS_MODULE",
"WeatherStation.settings")
django.setup()
application = get_default_application()
达芙妮现在不应该抱怨
daphne -p 8001 WeatherStation.asgi:application
在Apache中为Websocket配置ASGI和Daphne,对HTTP请求使用Apache。 Apache就像反向代理一样,将所有websocket请求重定向到运行在不同端口上的Daphne服务器
leafpad /etc/apache2/sites-available/000-default.conf
和内容
...
RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC,OR]
RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC]
RewriteRule .* ws://127.0.0.1:8001%{REQUEST_URI} [P,QSA,L]
Alias /static /home/pi/Dev/WeatherStation/static
<Directory /home/pi/Dev/WeatherStation/static>
Require all granted
</Directory>
<Directory /home/pi/Dev/WeatherStation/WeatherStation>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIDaemonProcess Dev python-path=/home/pi/Dev python-home=/home/pi/Dev/WSenv
WSGIProcessGroup Dev
WSGIScriptAlias / /home/pi/Dev/WeatherStation/WeatherStation/wsgi.py
</VirtualHost>
确保Apache有权访问您的数据库和其他内容
chmod g+w ~/dvds/db.sqlite3
chmod g+w ~/dvds
sudo chown :www-data db.sqlite3
sudo chown :www-data ~/dvds
重新启动Apache,以使这些更改生效:
sudo service apache2 restart
现在您已经有一个运行在Apache中的WSGI服务器和一个用于网络套接字的Daphne服务器