您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

带websockets和python / django(/扭曲?)

带websockets和python / django(/扭曲?)

我是django- websocket的作者。我不是Websocket和网络领域的真正专家,但是我认为我对所发生的事情有很好的了解。对不起,我很详细。即使大多数答案不是特定于您的问题,也可能会在其他时候为您提供帮助。:-)@H_403_1@

让我简短地解释一下什么是websocket。Websocket的启动看起来像是一个简单的HTTP请求,是通过浏览器建立的。它通过HTTP标头指示它希望将协议“升级”为Web套接字而不是HTTP请求。如果服务器支持websocket,则表示同意握手,并且服务器和客户端现在都知道它们将使用以前用于HTTP请求的已建立tcp套接字作为连接来交换websocket消息。@H_403_1@

除了发送和等待消息外,他们当然还具有随时关闭连接的能力。@H_403_1@

现在,让我们详细了解django-websocket如何在django请求-响应网络中实现HTTP请求的“升级”。@H_403_1@

Django通常使用WSGI规范来与Web服务器通信,例如apache或gunicorn等。该规范的设计仅考虑到HTTP的通信模型非常有限。它假定它获取一个HTTP请求(仅传入数据)并返回响应(仅传出数据)。这使得将django强制引入允许双向通信的websocket的概念非常棘手。@H_403_1@

我在django- websocket中为实现此目的而做的是,我非常深入地研究了WSGI的内部和django的请求对象以检索底层套接字。然后,此tcp套接字用于直接处理将HTTP请求升级到websocket实例。@H_403_1@

@H_403_1@

我希望以上内容可以使我们很明显,当建立一个websocket时,没有必要返回HttpResponse。这就是为什么通常在django- websocket处理的视图中不返回任何内容的原因。@H_403_1@

但是,我想坚持一个视图的概念,该视图包含逻辑并根据输入返回数据。这就是为什么您应该只在视图中使用代码来处理websocket的原因。@H_403_1@

从视图返回后,websocket将自动关闭。这样做是有原因的:我们不想在不确定的时间内保持打开套接字的状态,而不必依靠客户端(浏览器)将其关闭。@H_403_1@

这就是为什么您无法在视图外部使用django-websocket访问websocket的原因。然后,当然将文件描述符设置为-1,表明其已关闭。@H_403_1@

上面我解释说,我正在django的周围环境中进行挖掘,以某种方式-以一种非常骇俗的方式- 访问底层套接字。这非常脆弱,而且由于WSGI并非为此目的而设计,因此也不应该起作用!上面我还解释了视图结束后websocket是关闭的-但是,在websocket关闭(并关闭了tcp套接字)之后,django的WSGI实现尝试发送HTTP响应-它不知道websockets并认为它在正常的HTTP请求-响应周期。但是套接字已经关闭,发送将失败。这通常会在Django中引起异常。@H_403_1@

这并没有影响我对开发服务器的测试。浏览器永远不会注意到(您知道..套接字已经关闭;-)-但是在每个请求中引发未处理的错误不是一个很好的概念,并且可能会泄漏内存,无法正确处理数据库连接关闭以及许多麻烦的事情如果您使用django- websocket进行更多的实验,那 在某些时候中断。@H_403_1@

这就是为什么我会真正建议您 。它不是设计使然。Django(尤其是WSGI)将需要进行全面改革以解决这些问题(有关Websockets和WSGI的信息,请参阅此讨论)。从那时起,我建议使用诸如eventlet之类的东西。Eventlet具有有效的websocket实现(我从eventlet借用了django- websocket初始版本的一些代码),由于它只是纯Python代码,因此您可以从django中导入模型和其他所有内容。唯一的缺点是您需要第二个运行的Web服务器来处理websocket。@H_403_1@

python 2022/1/1 18:36:28 有441人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶