websockets有趣的部分是从服务器向浏览器发送本质上未经请求的内容,对吗?
好吧,我正在使用GregorMüllegger的django-websocket。使Websockets在Django中工作确实是一个很棒的早期尝试。
我完成了“ hello world”。它的工作方式是:当请求是websocket时,会将对象websocket附加到请求对象。因此,在解释websocket的视图中,我可以执行以下操作:
request.websocket.send('We are the knights who say ni!')
很好 我在浏览器中收到的消息像超级按钮一样。
但是,如果我不想在不发出浏览器请求的情况下进行操作,该怎么办?
OK,所以首先我将websocket保存在会话字典中:
request.session['websocket'] = request.websocket
然后,在外壳中,我按会话密钥获取会话。当然,会话字典中有一个websocket对象。快乐!
但是,当我尝试执行以下操作时:
>>> session.get_decoded()['websocket'].send('With a herring!')
我得到:
Traceback (most recent call last):
File "<console>", line 1, in <module>
error: [Errno 9] Bad file descriptor
好的,所以我对套接字一无所知,但是我知道足以在调试器中四处嗅探,瞧瞧,我发现调试器中的套接字(与请求中的真正websocket绑定在一起)具有fd = 6,而我从会话保存的Websocket中抢到的那个具有fd = -1。
面向套接字的人可以帮助我解决这些问题吗?
我是django-websocket的作者。我不是Websocket和网络领域的真正专家,但是我认为我对所发生的事情有很好的了解。很抱歉,进入细节。即使大多数答案不是特定于你的问题,也可能会在其他时候为你提供帮助。:-)
网络套接字如何工作
让我简短地解释一下什么是网络套接字。Websocket的开始看起来像是从浏览器建立的普通HTTP请求。它通过HTTP标头指示它希望将协议“升级”为Web套接字而不是HTTP请求。如果服务器支持websocket,则表示同意握手,并且服务器和客户端现在都知道它们将使用以前用于HTTP请求的已建立tcp套接字作为连接来交换websocket消息。
除了发送和等待消息外,他们当然还具有随时关闭连接的能力。
django-websocket如何滥用python的wsgi请求环境来劫持套接字
现在,让我们详细了解django-websocket如何在django请求-响应网络中实现HTTP请求的“升级”。
Django通常使用WSGI规范来与Web服务器通信,例如apache或gunicorn等。该规范的设计仅考虑到HTTP的通信模型非常有限。它假定它获取一个HTTP请求(仅传入数据)并返回响应(仅传出数据)。这使得将django强制引入允许双向通信的websocket的概念非常棘手。
我在django-websocket中为实现此目的而做的是,我非常深入地研究了WSGI和django的请求对象以检索底层套接字的内部。然后,此tcp套接字用于直接处理将HTTP请求升级到websocket实例。
现在到你的原始问题…
我希望以上内容可以使我们很明显,当建立一个websocket时,没有必要返回HttpResponse。这就是为什么通常在django-websocket处理的视图中不返回任何内容的原因。
但是,我想坚持一个视图的概念,该视图包含逻辑并根据输入返回数据。这就是为什么你只应在视图中使用代码来处理websocket的原因。
从视图返回后,websocket将自动关闭。这样做是有原因的:我们不想在不确定的时间内保持打开套接字的状态,而不必依靠客户端(浏览器)将其关闭。
这就是为什么你无法在视图外部使用django-websocket访问websocket的原因。然后,当然将文件描述符设置为-1,表明其已关闭。
免责声明
上面我曾解释说,我正在django的周围环境中进行挖掘,以便以一种非常骇人听闻的方式来访问底层套接字。这非常脆弱,而且由于WSGI并非为此而设计,因此也不应该起作用!上面我还解释了视图结束后websocket是关闭的-但是,在websocket关闭(并关闭了tcp套接字)之后,django的WSGI实现尝试发送HTTP响应-它不知道websockets并认为它在正常的HTTP请求-响应周期。但是套接字已经关闭,发送将失败。这通常会在Django中引起异常。
这并没有影响我对开发服务器的测试。浏览器永远不会注意到(你知道..套接字已经关闭;-)-但是在每个请求中引发未处理的错误不是一个很好的概念,并且可能会泄漏内存,无法正确处理数据库连接关闭以及许多麻烦的事情如果你使用django-websocket进行更多的实验,那将在某些时候中断。
这就是为什么我真的建议你不要将Websocket与django一起使用的原因。它不是设计使然。Django(尤其是WSGI)将需要彻底检查以解决这些问题(有关Websockets和WSGI的信息,请参阅此讨论)。从那时起,我建议使用诸如eventlet之类的东西。Eventlet具有有效的websocket实现(我从eventlet借用了django-websocket初始版本的一些代码),由于它只是纯Python代码,因此你可以从django中导入模型和其他所有内容。唯一的缺点是你需要运行另一个仅用于处理WebSocket的Web服务器。
问题内容: websockets有趣的部分是从服务器向浏览器发送本质上未经请求的内容,对吗? 好吧,我正在使用GregorMüllegger的django-websocket。使Websockets在Django中工作确实是一个很棒的早期尝试。 我完成了“ helloworld”。它的工作方式是:当请求是websocket时,会将对象websocket附加到请求对象。因此,在解释websocket
我已经使用Django频道(2.1.5版)在Django(2.0版)支持的网站上成功创建了websocket。 一切都很好,但我想知道CSRF代币怎么样。如果是WebSocket,是否需要它?文档中说,使用来防止这种线程已经足够了,但我想确保这一点。我是说,CSRF令牌发生了什么?我只是通过安全通道发送数据,而没有它,后端自动检查一切吗?如果是这样,为什么?为什么简单视图不能做到这一点? 我知道这
问题内容: 我是React-Redux的新技术,希望在某些实现方面对您有所帮助。 我想用套接字(socket.io)实现一个聊天应用程序。首先,用户必须注册(我在服务器端使用通行证),然后,如果注册成功,则用户必须连接到webSocket。 我认为最好的办法是对所有操作使用管道之类的中间件,并根据获取中间件的操作类型来执行不同的操作。 如果操作类型为,则创建客户端-服务器连接并设置所有将来自服务器
问题内容: 我正在尝试将服务器端Ajax响应脚本转换为,但显然无法正常工作。 这是服务器端脚本: 这是转换后的代码 我正在使用simplejson对Python列表进行编码(因此它将返回JSON数组)。我还不能弄清楚问题所在。但是我认为我对“回声”做错了。 问题答案: 我通常使用字典,而不是列表来返回JSON内容。 在Django 1.7之前的版本中,你将像这样返回它: 对于Django 1.7+
问题内容: 我正在尝试将服务器端Ajax响应脚本转换为Django HttpResponse,但显然无法正常工作。 这是服务器端脚本: 这是转换后的代码 我正在使用simplejson对Python列表进行编码(因此它将返回JSON数组)。我还不能弄清楚问题所在。但是我认为我对“回声”做错了。 问题答案: 我通常使用字典,而不是列表来返回JSON内容。 在Django 1.7之前的版本中,您将像这
我搜索了一下,只能找到这个关于socket.io0.9的wiki页面。 最终,我找到了engine.io-client的文档(socket.io-client基于1.x分支)。这是我写的代码,似乎正在工作。但是,我想知道这是正确的还是我做错了什么: 奇怪的是,仅仅将属性设置为仅具有的数组是不够的;我还必须禁用。这是正确的吗? 我有了一些新发现。 当仅设置为时,是否启用并没有什么区别。这正常吗?