django - Django-Channels 2 Apache CentOS 7 部署
问题描述
我不能让 Apache 通过 Daphne 服务 websocket。
requirements.txt settings.py
_
Django==2.0.7
channels==2.1.3
asgiref==2.3.2
redis==2.10.6
CHANNEL_LAYERS = {
"default":{
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [("localhost"), 6379],
},
"ROUTING": "myapp.routing.channel_routing",
},
}
ASGI_APPLICATION = "myapp.routing.application"
USE_WEBSOCKETS = True
路由.py
#..imports
websocket_urlpatterns = [
url(r"", MyConsumer),
]
application = ProtocolTypeRouter({
'websocket': AllowedHostsOriginValidator(
AuthMiddlewareStack(
URLRouter(
websocket_urlpatterns
)
)
)
})
asgi.py
#.. imports
os.environment.setdefault("DJANGO_SETTINGS_MODULE", "myapp.settings")
django.setup()
application = get_default_application()
我的消费者.py
#..imports
class MyConsumer(WebsocketConsumer):
def websocket_connect(self, event):
Logger.log("Connected " + json.dumps(event))
self.send({
"type": "websocket.accept"
})
def websocket_receive(self, event):
Logger.log("Receive " + json.dumps(event))
def websocket_disconnect(self, event):
Logger.log("Disconnected " + json.dumps(event))
httpd.conf
#...
RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC, OR]
RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC]
RewriteRule .* ws://127.0.0.1:9001%{REQUEST_URI} [P, QSA, L]
supervisord.conf
;...
[fcgi-program:asgi]
socket=tcp://127.0.0.1:9001
command=/var/www/venv/bin/daphne -u /run/daphne%(process_num)d.sock --fd 0 --access-log - --proxy-headers myapp.asgi.application
numprocs=2
process_name=asgi%(process_num)d
directory=/var/www/venv/myapp/
autostart=true
autorestart=true
stdout_logfile=/tmp/asgi.log
redirect_stderr=true
在javascript中,我只是尝试连接:
var location = window.location
var socket = new WebSocket('ws://' + location.host + ':9001' + location.pathname)
socket.onopen = function(e){
console.log('open', e)
}
socket.onerror = function(e){
console.log('error', e)
}
socket.onclose = function(e){
console.log('close', e)
}
每次访问页面时,它都会WebSocket connection to 'ws://127.0.0.1:9001/' failed: Error during WebSocket handshake: net::ERR_CONNECTION_RESET
在一段时间后给出并在控制台中打印错误和关闭消息。我按照readthedocs
提供的示例设置并使用了 nginx 实例,但它给出了相同的错误。
似乎后端没有收到消息,所以我想设置中肯定有一些东西,即消息队列或redis服务器。我错过了什么?
解决方案
是的,我对与您的设置类似的设置进行了相当多的故障排除。我目前在 centos 7.5 服务器上同时运行 channels2、daphne、redis 和 apache。最后完美运行。
我发现使用 AsyncConsumer 进行故障排除更容易,提供了更多控制。尝试做:
from channels.consumer import SyncConsumer, AsyncConsumer
class ChatConsumer(AsyncConsumer):
async def websocket_connect(self, event):
# when the socket connects
print(event)
await self.send({
"type": "websocket.accept"
})
然后您可以看到传入的数据(如果有)。
对于像你一样的 apache,我使用重写引擎。(在虚拟主机文件中)
RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC,OR]
RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC]
RewriteRule .* ws://127.0.0.1:9001%{REQUEST_URI} [P,QSA,L]
希望你弄清楚!/R
推荐阅读
- python-3.x - Flask-SocketIO 发送图片
- c# - EF Core 多对多隐藏枢轴
- spring - 带有Java Config的Spring autowire =“byType”?
- list - 列出序言中的交集
- elasticsearch - elasticsearch 通配符或正则表达式
- sorting - 排序地图分组按计数
- python - DoubleLinkedList 获取内存位置而不是节点值 - Python
- android - HTTPS 连接 - 如何管理密钥对
- r - 将多页pdf的每一页转换为R中单独的png文件
- ruby - Ruby:从陷阱上下文运行 irb?