Django通道2 Apache CentOS 7部署

Django通道2 Apache CentOS 7部署,django,apache,websocket,django-channels,daphne,Django,Apache,Websocket,Django Channels,Daphne,我不能让Apache通过Daphne提供WebSocket。 requirements.txt文件 Django==2.0.7 通道==2.1.3 asgiref==2.3.2 redis==2.10.6 设置.py CHANNEL_LAYERS = { "default":{ "BACKEND": "channels_redis.core.RedisChannelLayer", "CONFIG": { "hosts": [("lo

我不能让Apache通过Daphne提供WebSocket。
requirements.txt文件
Django==2.0.7
通道==2.1.3
asgiref==2.3.2
redis==2.10.6

设置.py

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
#..imports  

websocket_urlpatterns = [
    url(r"", MyConsumer),
]

application = ProtocolTypeRouter({
    'websocket': AllowedHostsOriginValidator(
        AuthMiddlewareStack(
            URLRouter(
                websocket_urlpatterns
            )
        )
    )
})
#.. imports

os.environment.setdefault("DJANGO_SETTINGS_MODULE", "myapp.settings")
django.setup()
application = get_default_application()
routing.py

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
#..imports  

websocket_urlpatterns = [
    url(r"", MyConsumer),
]

application = ProtocolTypeRouter({
    'websocket': AllowedHostsOriginValidator(
        AuthMiddlewareStack(
            URLRouter(
                websocket_urlpatterns
            )
        )
    )
})
#.. imports

os.environment.setdefault("DJANGO_SETTINGS_MODULE", "myapp.settings")
django.setup()
application = get_default_application()
asgi.py

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
#..imports  

websocket_urlpatterns = [
    url(r"", MyConsumer),
]

application = ProtocolTypeRouter({
    'websocket': AllowedHostsOriginValidator(
        AuthMiddlewareStack(
            URLRouter(
                websocket_urlpatterns
            )
        )
    )
})
#.. imports

os.environment.setdefault("DJANGO_SETTINGS_MODULE", "myapp.settings")
django.setup()
application = get_default_application()
MyConsumer.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]
;...    
[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
supervisord.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]
;...    
[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)
}
每次访问该页面时,它都会提供到“ws://127.0.0.1:9001/”的
WebSocket连接失败:WebSocket握手时出错:net::ERR_connection_RESET
,并在控制台中打印错误和关闭消息。
我遵循了在提供的示例设置,并使用了一个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,像你一样,我使用重写引擎。(在vhost文件中)

希望你能弄明白!
/R

是的,我将其更改为使用SyncConsumer,似乎可以正常工作,但现在出现了另一个问题-在apache中使用此配置时,utf8文件名存在问题(直接使用daphne时-使用nginx代理websocket流量时,unicode也没有问题,仅使用apache时-出于某种原因,虽然我将其设置为utf8,但它使用ascii字符集)