如何解决Django ASGI 通道应用程序不跟踪多个 websocket 客户端使用 redis 和 nginx 原始问题:
编辑:
在为我的 websockets 定义路由时,我错过了 .as_asgi(),这意味着我创建的每个实例都被我创建的下一个实例覆盖。
我的 routing.py 现在看起来像:
application = ProtocolTypeRouter({
'websocket': AllowedHostsOriginValidator(
AuthMiddlewareStack(
URLRouter(
[
url("calling/interface/",ChatConsumer.as_asgi()),]
)
)
)
})
原始问题:
我在本地虚拟机上托管了带有 asgi 频道的 Django,我也在使用 redis-channels 和 Nginx。我能够与一个用户连接并使用我的应用程序,但是一旦创建第二个连接,旧的(原始)客户端就会停止接收网络套接字信息,但它仍然可以发送它。我的consumers.py 接收到所有的websocket 数据,但认为它们都来自最新的连接。这意味着第一个 ws 连接确实关闭但停止接收信息。
版本:
Python = 3.9.2
Django = 3.1.7
Channels = 3.0.3
channels-redis = 3.2.0
redis = 5.0.3
我已经能够从消费者内部和外部发送 websocket 信息来处理 webhook 响应,但我无法处理消费者上的多个连接。
Nginx 配置:
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream websocket {
server 127.0.0.1:8000;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://websocket;
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-Formwarded-Host $server_name;
} # end location
} # end server
} # end http
消费者(减少):
class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.username = self.scope["session"]["tokeNowner"]
await self.accept()
await self.send(text_data="[Welcome %s!]" % self.username)
token = self.scope["session"]["token"]
webhook_response = await create_webhook()
await create_record(webhook_response.id)
print(f"New Channel: {self.channel_name}")
print(f"Webhook ID: {webhook_response.id}")
async def disconnect(self,message):
token = self.scope["session"]["token"]
closing_channel_name = self.channel_name
WebhookID = await get_self_record()
await asyncio.gather(delete_webhook(WebhookID))
await delete_record()
async def receive(self,text_data=None,bytes_data=None):
token = self.scope["session"]["token"]
instructions = text_data.split("_")
params = instructions[1:]
#instructions are send as a string with data split by '_'
#I handle the args sent and call a function based on them
async def call_update(self,event):
await self.send(text_data=event['text'])
如果您需要更多信息,请告诉我!
解决方法
在为我的 websockets 定义路由时,我错过了 .as_asgi(),这意味着我创建的每个实例都被我创建的下一个实例覆盖。
我的 routing.py 现在看起来像:
application = ProtocolTypeRouter({
'websocket': AllowedHostsOriginValidator(
AuthMiddlewareStack(
URLRouter(
[
url("calling/interface/",ChatConsumer.as_asgi()),]
)
)
)
})
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。