【发布时间】: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