Django channels和React的错误:WebSocket连接到'ws://localhost:8000/myURL'失败:WebSocket在建立连接之前就关闭了。

3
首先,我还不确定问题是在前端还是后端,但看起来更可能是后端的问题。
我使用django-channels构建了一个Django应用程序,通过websocket连接将数据包发送到前端react.js SPA。我之前也建立过一个简单的vanilla-javascript客户端(由Django提供服务),它没有这个问题。
问题是,在打开时我在Firefox控制台上得到了这个错误(它们在随机时间交替出现,表明它们同时发生):
Firefox can't establish a connection to the server at ws://localhost:8000/ws/XY_Broadcast/. App.jsx:32
The connection to ws://localhost:8000/ws/XY_Broadcast/ was interrupted while the page was loading. App.jsx:32

使用基于Chromium的Brave浏览器,我得到了以下结果:
(warning) App.jsx:69 WebSocket connection to 'ws://localhost:8000/ws/XY_Broadcast' failed: WebSocket is closed before the connection is established.
(error)App.jsx:38 WebSocket connection to 'ws://localhost:8000/ws/XY_Broadcast' failed: 

奇怪的是,我的页面似乎可以打开并工作 - 它会在打开后和一段时间后接收到数据时打印消息。 WebSocket错误代码为1006。
我尝试过: - 尝试了一些浏览器扩展程序来测试WebSocket连接 - 没有一个能够连接(这就是我认为这是后端问题的原因)。 - 我也不认为问题与CORS有关 - 我以前曾遇到过它的问题(我的前端应用程序无法显示从后端获取的HTTP URL图像),并且我有一个扩展程序在浏览器中启用/禁用它 - 它不会影响任何内容。 - 我尝试根据django-channels文档中提到的方式将Django设置的ASGI_APPLICATION更改为myproject.asgi.application,但没有帮助,所以我将其设置回myApp.routing.application。 - 我尝试使用daphne而不是runserver运行项目,在我的docker-compose文件中,我有"daphne -b 0.0.0.0 -p 8000 some_demo_django.asgi:application"。React页面可以打开并显示从后端获取的图像,但仍然存在错误。此外,旧的(vanilla JS页面)无法加载,我得到“500 Internal Server Error Daphne HTTP processing error”,并从后端获得以下traceback信息:
  File "/usr/local/lib/python3.10/site-packages/daphne/http_protocol.py", line 163, in process
    self.application_queue = yield maybeDeferred(
TypeError: ASGIHandler.__call__() missing 2 required positional arguments: 'receive' and 'send'

172.19.0.1:41728 - - [13/Oct/2022:00:06:48] "GET /dev_td/" 500 452
172.19.0.1:41718 - - [13/Oct/2022:00:06:49] "WSDISCONNECT /ws/XY_Broadcast" - -
2022-10-13 00:06:49,429 ERROR    Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/daphne/http_protocol.py", line 163, in process
    self.application_queue = yield maybeDeferred(
TypeError: ASGIHandler.__call__() missing 2 required positional arguments: 'receive' and 'send'
172.19.0.1:41728 - - [13/Oct/2022:00:06:49] "GET /dev_td/" 500 452
2022-10-13 00:06:55,721 ERROR    Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/daphne/http_protocol.py", line 163, in process
    self.application_queue = yield maybeDeferred(
TypeError: ASGIHandler.__call__() missing 2 required positional arguments: 'receive' and 'send'

React代码如下:

export default function App() {
  const [messages, setMessages] = useState([]);
  useEffect(() => {
    const ws = new WebSocket('ws://localhost:8000/ws/XY_Broadcast/');
    ws.onopen = (event) => {
      console.log(event.data)
      console.log('ws opened')
    };
    ws.onmessage = function (event) {
        console.log(event.data)
    };
    ws.onclose = function(event){
      console.log("closed, code is:",event.code)
    };
    return () => ws.close();
  }, []);

之前编写的原始JavaScript客户端代码如下:

  var XY_Broadcast = new WebSocket(
    'ws://' + window.location.host + '/ws/XY_Broadcast/');

  XY_Broadcast.onmessage = function(e) {
    let loc_data = JSON.parse(e.data);

  ... (my logic) 

  XY_Broadcast.onclose = function (e) {
    console.error('XY_Broadcast socket connection closed');
    for(var i=0; i<e.length; i++) {
      console.log(e)
    }
  };

我已经在互联网上浏览了所有能找到的答案,并与公司的高级开发人员讨论了这个问题,但没有成功。

1个回答

5

当你试图在WebSocket连接实际建立之前关闭WebSocket连接ws.close()时,会发生这种情况。

尝试更改useEffect清除函数:

return () => ws.close();

to :

return () => {
            if (socket.readyState === 1) { 
                socket.close();
            }

哦,等等,我以为它已经为我修复了,但是它没有起作用——几秒钟后,错误仍然出现: WebSocket connection to 'ws://localhost:8000/myURL' failed:
但是,至少我不会再收到 WebSocket is closed before the connection is established 错误。
- illevens
const ws = new WebSocket('ws://localhost:8000/ws/XY_Broadcast/');更改为const ws = new WebSocket('ws://127.0.0.1:8000/ws/XY_Broadcast/');,传递IP而不是localhost - monim
如果有问题,请告诉我。 - monim
嗯...它确实做到了。再次感谢你,亲切的陌生人! - illevens
1
哇,谢谢!比GPT-4-32K带有所有花里胡哨的东西还要好。 - Joseph Adam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接