Python 无法通过websockets连接(daphne、django、nginx、docker)
带django、docker compose、nginx、daphne的Websocket 常规http连接工作正常,但websocket连接没有输出。websocket似乎未处于活动状态 通过javascript连接会产生错误:Python 无法通过websockets连接(daphne、django、nginx、docker),python,django,docker,nginx,websocket,Python,Django,Docker,Nginx,Websocket,带django、docker compose、nginx、daphne的Websocket 常规http连接工作正常,但websocket连接没有输出。websocket似乎未处于活动状态 通过javascript连接会产生错误: newwebsocket('ws://127.0.0.1:8000/ws/pollData'); //到“ws://127.0.0.1:8000/ws/pollData”的WebSocket连接失败: 或者在连接到ws://localhost/ws/pollData
newwebsocket('ws://127.0.0.1:8000/ws/pollData');
//到“ws://127.0.0.1:8000/ws/pollData”的WebSocket连接失败:
或者在连接到ws://localhost/ws/pollData时:
newwebsocket('ws://localhost/ws/pollData');
//未选中的runtime.lastError:无法建立连接。接收端不存在。
docker-compose.yaml
version: '3'
services:
volume_configurer:
image: busybox
volumes:
- shared:/shared:z
- static:/static:z
command: ["/bin/sh", "-c", "
mkdir -p /static;
chmod -R 777 /static;
mkdir -p /shared/sync;
chmod -R 777 /shared/sync;
echo STARTED > /shared/sync/volumesetter && chmod a+r /shared/sync/volumesetter"]
db:
container_name: postgresdb
image: postgres:latest
restart: always
env_file:
- project.env
ports:
- 5432:5432
volumes:
- postgres-data1:/var/lib/postgresql/data1:z
web:
build:
context: ./
dockerfile: ./mdb/Dockerfile
container_name: django
command: >
daphne mdb.asgi:application -b 0.0.0.0 -p 8000
env_file:
- project.env
expose:
- 8000
depends_on:
- db
volumes:
- ./mdb:/home/app/web/:z
- static:/home/app/web/static/:z
- shared:/uploads/:z
nginx:
container_name: nginx
image: nginx
restart: always
ports:
- 80:80
volumes:
- ./nginx:/etc/nginx/conf.d:z
- static:/home/app/web/static/:z
depends_on:
- web
- db
volumes:
postgres-data1:
static:
shared:
nginx.conf:
upstream mdb {
server django:8000;
}
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
server_name localhost;
client_max_body_size 2000M;
location /static/ {
alias /home/app/web/static/;
}
location /ws/ {
proxy_pass http://mdb;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
location / {
try_files $uri @proxy_to_app;
}
location @proxy_to_app {
proxy_pass http://mdb;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
consumer.py
从channels.generic.websocket导入WebsocketConsumer
导入json
DashConsumer类(WebsocketConsumer):
def连接(自):
打印('===============================2')
self.accept()
def断开连接(自身、关闭_代码):
打印('============================1')
通过
def接收(自身、文本数据):
打印('=========================0')
text\u data\u json=json.load(text\u数据)
message=text\u data\u json['message']
self.send(text_data=json.dumps({
“消息”:消息
})
)
从python视图来看,连接到ws://localhost:8000/ws/pollData
时,连接到websocket不会产生任何输出。然而,它也不会崩溃。而当连接到其他东西时,比如说,ws://localhost/ws/pollData
,它会因连接被拒绝而崩溃。但是,当使用ws.connect()时,django没有输出,即consumer.py中的print('=========================')
未启动
views.py
ws=websocket.websocket()
#不打印
打印(ws.connect('ws://localhost:8000/ws/pollData'))
#也不打印
打印(ws.send(“{”消息“:“来自django的测试”}”)
#打印“还在这里”
打印('仍在此处')
#这个崩溃了
打印(ws.connect('ws://localhost:8000/ws/pollData'))
#不打印
打印('仍在此处')
asgi.py
导入操作系统
从django.conf.url导入url
从django.core.asgi导入获取\u asgi\u应用程序
os.environ.setdefault(“DJANGO\u设置\u模块”、“mdb.SETTINGS”)
django_asgi_app=get_asgi_application()
从channels.auth导入AuthMiddlewareStack
从channels.routing导入协议类型路由器,URLRouter
从chat.consumer导入DashConsumer
应用程序=协议类型路由器({
“http”:django_asgi_应用程序,
“websocket”:AuthMiddlewareStack(
URLRouter([
url(r“^ws/pollData$”,DashConsumer.as_asgi()),
])
),
})
设置.py
WSGI_APPLICATION = 'mdb.wsgi.application'
ASGI_APPLICATION = 'mdb.routing.application'
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels.layers.InMemoryChannelLayer"
},
}
非常感谢您的帮助
编辑:
当使用ws://localhost/ws/pollData
或ws://0.0.0.0/ws/pollData
的地址时,javascript似乎正在连接,因为在这两种情况下都会发生连接事件,并且网络面板显示打开的websocket连接。但是,在python中,这两个地址都会导致连接被拒绝,即:
ws=websocket.websocket()
#似乎已连接,但未向javascript发送任何内容
connect('ws://localhost:8000/ws/pollData')
send(“{”消息“:“从django进行测试”}”)
#撞车
connect('ws://localhost/ws/pollData')
#也崩溃
connect('ws://0.0.0.0/ws/pollData')
将DashConsumer
更改为AsyncJsonWebsocketConsumer
,同时注意到websocket实际上是在另一个地址用javascript打开的(即ws://localhost/ws/pollData
或ws://0.0.0/ws/pollData
)
class DashConsumer(AsyncJsonWebsocketConsumer):
打印('=========================0')
异步def连接(自):
打印('============================1')
self.groupname='dashboard'
等待self.channel\u layer.group\u添加(
self.groupname,
self.channel\u名称,
)
等待自我接受
异步def断开连接(自身、关闭代码):
打印('===============================2')
等待self.channel\u layer.group\u丢弃(
self.groupname,
self.channel\u名称
)
异步def接收(自身、文本数据):
打印('===============================3')
#~#datapoint=json.load(文本数据)
#~#val=datapoint['value']
val=文本数据
等待self.channel\u layer.group\u发送(
self.groupname,
{
'type':'deprocessing',#要运行的函数名
“值”:val#发送函数的值
}
)
打印(“>>>”,文本数据)
异步def去处理(自、事件):
打印('===============================4')
valOther=事件['value']
valOther=f'IP值:{valOther}'
#发送到前端
等待self.send(text_data=json.dumps({'value2':valOther}))
views.py
ws=websocket.websocket()
connect('ws://localhost:8000/ws/pollData')
send(“{”消息“:“从django进行测试”}”)