![](/img/trans.png)
[英]How to get ip address of a client that connect to a websocket server in FastAPI?
[英]How do I get the client IP address of a websocket connection in Django Channels?
我需要获取 websocket 连接的客户端 IP 地址,以实现我想要实现的一些额外功能。 我有一个现有部署的 Django 服务器运行 Nginx-Gunicorn-Uvicorn Worker-Redis 配置。 正如人们所预料的那样,在开发过程中,在运行本地服务器的同时,一切都按预期进行。 但是,在部署时,当我尝试通过self.scope["client"][0]
访问 websocket 的客户端 IP 地址时,我收到错误NoneType object is not subscriptable
。
下面是配置和代码: NGINX Config:
upstream uvicorn {
server unix:/run/gunicorn.sock;
}
server {
listen 80;
server_name <ip address> <hostname>;
location = /favicon.ico { access_log off; log_not_found off; }
location / {
include proxy_params;
proxy_set_header Connection "";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://uvicorn;
proxy_headers_hash_max_size 512;
proxy_headers_hash_bucket_size 128;
}
location /ws/ {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_redirect off;
proxy_pass http://uvicorn;
}
location /static/ {
root /var/www/serverfiles/;
autoindex off;
}
location /media {
alias /mnt/apps;
}
}
Gunicorn Config:注意:为了便于阅读,ExecStart 已被格式化,它是实际配置中的一行
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
User=django
Group=www-data
WorkingDirectory=/srv/server
Environment=DJANGO_SECRET_KEY=
Environment=GITEA_SECRET_KEY=
Environment=MSSQL_DATABASE_PASSWORD=
ExecStart=/bin/bash -c "
source venv/bin/activate;
exec /srv/server/venv/bin/gunicorn
--workers 3
--bind unix:/run/gunicorn.sock
--timeout 300
--error-logfile /var/log/gunicorn/error.log
--access-logfile /var/log/gunicorn/access.log
--log-level debug
--capture-output
-k uvicorn.workers.UvicornWorker
src.server.asgi:application
"
[Install]
WantedBy=multi-user.target
代码抛出错误:
@database_sync_to_async
def _set_online_if_model(self, set_online: bool) -> None:
model: MyModel
for model in MyModel.objects.all():
if self.scope["client"][0] == model.ip:
model.online = set_online
model.save()
在我需要访问连接客户端 IP 地址之前,该服务器在其当前配置下一直运行得非常好。 它可以很好地处理其他 websocket 连接,没有任何问题。
我已经研究过根据文档尝试配置我自己的自定义 UvicornWorker。 我根本不是这方面的专家,所以我可能误解了我应该做的事情: https://www.uvicorn.org/deployment/#running-behind-nginx
from uvicorn.workers import UvicornWorker
class ServerUvicornWorker(UvicornWorker):
def __init__(self, *args, **kwargs) -> None:
self.CONFIG_KWARGS.update({"proxy_headers": True, "forwarded_allow_ips": "*"})
super().__init__(*args, **kwargs)
我还查看了https://github.com/django/channels/issues/546 ,其中提到了 Daphne 的--proxy-headers
配置,但是,我没有运行 Daphne。 https://github.com/django/channels/issues/385提到 HTTP 标头被传递给消费者的connect
方法,但是,该帖子很旧,据我所知不再相关。 我的连接方法没有得到任何额外的**kwargs
。
客户端IP 与频道无关
self.scope["client"][0] 未定义,因为当您在后端从前端接收数据时,没有名称为 client 的数据。 所以尝试从前端发送它。 可以先发一份手册,static的值先验证一下,然后找技术读取IP地址再发。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.