【问题标题】:Socket IO transport 404套接字 IO 传输 404
【发布时间】:2022-01-05 04:25:53
【问题描述】:

我正在尝试使用服务器端 react 和 python 连接一个简单的 socket-io 应用程序。我在套接字连接上得到一个 404。问题是有太多的移动部件让我知道发生了什么并调试错误(即 NGINX、python、react、Cloudflare)。代码是尽可能简单的原型示例。

这是 NGINX 代码 -

server {
  
    listen 80;
    listen [::]:80;
    server_name abookoftwelveflowers.com www.abookoftwelveflowers.com;
    return 302 https://$server_name$request_uri;

}

server {

    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    ssl                    on;
    ssl_certificate         /etc/ssl/certs/cloudflare_book.pem;
    ssl_certificate_key     /etc/ssl/private/cloudflare_book.pem;

    server_name abookoftwelveflowers.com www.abookoftwelveflowers.com;

    location / {
            #root /NEST/stream/front/build;
            #index index.htl index.htm
            proxy_pass http://unix:/NEST/stream/back_flask/guni_one.sock;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
    }
}

这是 Python 代码 -

独角兽

#!/bin/bash
cp -r /NEST/stream/front/files /NEST/stream/front/build/files
gunicorn --workers 3 --bind unix:guni_two.sock -m 007  wsgiapi:app --daemon

wsgi.py

#!/bin/env python
  

from my_app import app, sio

if __name__ == '__main__':
    sio.run(app, debug=True)
    #app.run(host="0.0.0.0", port=4000, debug=True, threaded=True, ssl_context="adhoc")

my_app.py

from flask import Flask, send_from_directory, request
from flask_cors import CORS
from flask_socketio import SocketIO

#import socketio
import requests
import json

app = Flask(__name__, static_folder="../front/build", static_url_path="/")
CORS(app)

sio = SocketIO()

@sio.on('connect')
def test_connect(auth):
    emit('my response', {'data': 'Connected'})

@sio.on('disconnect')
def test_disconnect():
    print('Client disconnected')

@sio.on('message')
def handle_message(data):
    print('received message: ' + data)

@app.route("/")
def hello_world():
    return app.send_static_file("index.html")

...other routes...

在我的应用程序的主页上

import Navigation from "../components/Navigation.js"
import Webcounter from "../components/Webcounter.js"

import React, {useEffect, useState} from "react";
import {useHistory} from "react-router-dom";
import { io } from "socket.io-client";

function Main() {
  let history = useHistory();

  const socketfunc = () => {
    console.log('inside socketfunc in Main.js');
    const socket = io('https://www.abookoftwelveflowers.com')
    console.log('value of socket: ', socket);
    socket.on('connect', (socket) => {
      console.log('value of socket inside connect: ', socket);
    })
  }

  useEffect(()=>{
    console.log('inside useEffect for Main.js')
    socketfunc()
  }, []);

当我运行代码时,网站可以运行 - 我可以访问前端和后端路由,但是 socket io 反复失败,并且 Web 控制台中的错误是这样的 -

GET https://www.abookoftwelveflowers.com/socket.io/?EIO=4&transport=polling&t=NrXngtX 404
            

这与/var/log/nginx/ 的输出相匹配,如下所示:

172.70.178.17 - - [27/Nov/2021:14:49:49 +0000] "GET /socket.io/?EIO=4&transport=polling&t=NrXtx0u HTTP/2.0" 502 568 "https://abookoftwelveflowers.com/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36"

所以,我认为问题来自 NGINX,因为我使用 .sock 作为 proxy_pass,但我不确定到底是什么。这是我(最终)能够让 NGINX 工作的方式,所以如果我不需要,我不想将其更改为使用端口号。有什么建议吗?

关于如何调试这个有什么建议吗?

编辑-

所以这有很多动人的部分,我想我更接近下面的评论/建议,将SocketIo() 更改为SocketIo(app)。抱歉,如果这不是一个理想的“我如何解决 x 错误”,但是通过多个程序进行堆栈跟踪很困难。我所做的更改如下

在客户端 -

  const socketfunc = () => {
    console.log('inside socketfunc in Main.js');
    const socket = io('https://www.abookoftwelveflowers.com', {path: '/socket.io'})
    console.log('value of socket: ', socket);
    socket.on('connect', (socket) => {
      console.log('value of socket inside connect: ', socket);
    })
  }

在服务器上 -

sio = SocketIO(app, cors_allowed_origins="*", path='/socket.io')

在独角兽中-

gunicorn --workers 1 --bind unix:guni_one.sock -m 001  wsgi:app

在 NGINX 中 -

location /socket.io/ {
    include proxy_params;
    proxy_http_version 1.1;
    proxy_buffering off;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    #proxy_pass http://127.0.0.1:5000;
    proxy_pass http://unix:/NEST/stream/back_flask/guni_one.sock;
}

location / {
    proxy_pass http://unix:/NEST/stream/back_flask/guni_one.sock;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
}

我尝试在 gunicorn 和 NGINX 中使用 0.0.0.0:<PORT> 并尝试使用 /socket.io//socket.io 来发送请求。据我所知,传入和传出请求是对称的。

我还将 gunicorn 设置为只有一名工人。文档 (https://flask-socketio.readthedocs.io/en/latest/deployment.html) 令人困惑,因为它说如果您使用 socketio.run(app),那么工人的数量可能会或可能不会重要,但以防万一......

无论如何,我有以下错误。从我可以在线阅读的内容(What can lead to "IOError: [Errno 9] Bad file descriptor" during os.system()?)来看,OS ERROR Bad File Descriptor 是由于没有正确关闭文件读/写。为什么这应该发生在我不知道的套接字调用上。

这是错误。一旦记录了错误,gunicorn 会杀死工作人员并循环另一个,尝试重新连接套接字,然后工作人员再次死亡。我将继续调试,但如果有任何建议会令人愉快。谢谢

Invalid session K13_ryJcNNXj7dKWAAAn (further occurrences of this error will be logged with level INFO)
Client disconnected
inside the test_connect handler
[2021-11-27 23:50:05 +0000] [3422698] [ERROR] Socket error processing request.
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/gunicorn/workers/sync.py", line 134, in handle
    self.handle_request(listener, req, client, addr)
  File "/usr/lib/python3/dist-packages/gunicorn/workers/sync.py", line 190, in handle_request
    util.reraise(*sys.exc_info())
  File "/usr/lib/python3/dist-packages/gunicorn/util.py", line 650, in reraise
    raise value
  File "/usr/lib/python3/dist-packages/gunicorn/workers/sync.py", line 181, in handle_request
    resp.write(item)
  File "/usr/lib/python3/dist-packages/gunicorn/http/wsgi.py", line 326, in write
    self.send_headers()
  File "/usr/lib/python3/dist-packages/gunicorn/http/wsgi.py", line 322, in send_headers
    util.write(self.sock, util.to_bytestring(header_str, "latin-1"))
  File "/usr/lib/python3/dist-packages/gunicorn/util.py", line 311, in write
    sock.sendall(data)
OSError: [Errno 9] Bad file descriptor

【问题讨论】:

    标签: reactjs sockets nginx flask socket.io


    【解决方案1】:

    我想我知道它为什么不起作用。您放入 Flask 应用程序:

    app = Flask(__name__, static_folder="../front/build", static_url_path="/")

    这就是说将静态路径作为根路径。换句话说,如果您的应用程序中没有明确的路由,那么它会尝试从../front/build 查找并提供文件。

    这也可以解释您的 nginx 日志中的 502 - Bad Gateway 错误。

    编辑:我已经测试了这个理论,它似乎没有影响任何东西。但是,现在我看到你刚刚做到了

    sio = SocketIO()

    没有传入app,这可能是它不起作用的另一个原因。

    【讨论】:

    • 这是问题的一部分!请参阅上面的编辑 - 感谢您的建议!
    猜你喜欢
    • 2018-09-17
    • 2017-10-14
    • 2017-01-24
    • 2014-11-03
    • 2014-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多