当前位置: 首页 > 知识库问答 >
问题:

烧瓶SocketIO uWSGI。与骡工合作

子车安和
2023-03-14

最近,我在Flask应用程序中实现了WebSocket支持。

安装程序如下所示:1。Python 2.7.2。3号烧瓶。SocketIO(客户端)4。NGINX作为代理5。uWSGI 2.0.13它是带有Gevent的WebSocket(猴子补丁)

我已经成功地启用了套接字连接,但在UWSGI工作人员(尤其是单mule)之间的发射同步方面,我遇到了困难。

我专门用UWSGI mule监控一些东西,每30秒报告一次状态,并将其广播给连接的客户。如果我允许我的任务在任何可用的worker(不仅仅是mule专用的)上运行,则只会发送到以前通过完全相同的过程作为服务器的客户端,例如:worker#6使用(400 PID)和已建立的套接字连接来服务客户端请求。后来,一个mule任务由同一个工作者提供服务,因此客户端接收到Emit(如果任何其他工作者处理该任务,则客户端不会缓存Emit)。

在单工作模式下,一切正常,但这显然不是可接受的解决方案。

以下是一些技术细节:uwsgi.ini

[uwsgi]
#application's base folder
base = /home/ubuntu/application_test

#python module to import
app = manage
module = %(app)

home = %(base)/venv
virtualenv = %(base)/venv
pythonpath = %(base)

#socket file's location
socket = %(base)/application_test.sock

#permissions for the socket file
chmod-socket = 666

#the variable that holds a flask application inside the module imported at 
line #6
callable = app

#location of log files
logto = /var/log/uwsgi/%n.log

processes = 10

#WebSocket
http-websockets = true

gevent = 1000
enable-threads = true
die-on-therm = true

vacuum = true

mule=%(base)/application_test/uwsgi_mules/metrics_mule.py

烧瓶应用程序

(...)
from flask_socketio import SocketIO
app = Flask(__name__)
socketio = SocketIO(app,message_queue='redis://')
(...)

工作者发射代码

socket = SocketIO(message_queue='redis://')

def broad_cast_server_info(state, health):
    socket.emit('sys_state', health)
    socket.emit('system_snapshot', state)

客户端

        socket.on('sys_state', function(data){
            (...)
            }
        });

如果我使用客户端socket.emit确认响应,一切正常。

在mule中,我只需导入socketio并在其上调用emit,就面临上述问题。但是,如果我遵循:https://flask-socketio.readthedocs.io/en/latest/#emitting-来自外部进程

每次骡子运行它的工作时,我都会得到一个redis错误。

文件“/home/ubuntu/application\u test/venv/local/lib/python2.7/site packages/flask\u socketio/init.py”,第365行,在emit-skip\u-sid=skip\u-sid,callback=callback,**kwargs)文件“/home/ubuntu/application\u test/venv/local/lib/python2.7/site packages/socketio/server.py”,第228行,在emit************“/home/ubuntu/application\u test/venv/local/lib/python2.7/site packages/socketio/pubsub\u manager.py”,第66行,在发布返回self.redis.publish(self.channel,pickle.dumps)文件/home/ubuntu/application\u test/venv/local/lib/python2.7/site packages/socketio/redis\u manager.py”第62行文件“/home/ubuntu/application_test/venv/local/lib/python2.7/site packages/redis/client.py”,第2034行,在发布返回self.execute_命令(“发布”,频道,消息)文件“/home/ubuntu/application_test/venv/local/lib/python2.7/site packages/redis/client.py”,第673行,在执行_命令连接中。发送_命令(*args)文件”/home/ubuntu/application_test/venv/local/lib/python2.7/site packages/redis/connection.py”,第610行,在send_命令self.send_packed_命令(self.pack_命令(*args))文件/home/ubuntu/application_test/venv/local/lib/python2.7/site packages/redis/connection.py中,第585行,在send_packed_命令self.connect.connect()文件中/home/ubuntu/application_test/venv/local/lib/python2.7/site packages/redis/connection.py”,第489行,在connect raise ConnectionError(self._error_message(e))redis.exceptions.ConnectionError:error-2连接到redispass:6379.名称或服务未知。

PIP冻结:

alabaster==0.7.9
amqp==2.1.1
aniso8601==1.2.0
appdirs==1.4.3
astroid==1.4.8
Babel==2.3.4
beautifulsoup4==4.5.1
certifi==2017.11.5
chardet==3.0.4
click==6.7
decorator==4.0.11
defusedxml==0.5.0
dict2xml==1.5
dicttoxml==1.7.4
docopt==0.6.2
enum-compat==0.0.2
enum34==1.1.6
eventlet==0.21.0
Flask==0.12
Flask-Login==0.4.0
Flask-RESTful==0.3.5
flask-restful-swagger-2==0.33
Flask-Script==2.0.5
Flask-SocketIO==2.9.2
flask-swagger-ui==0.0.3
Flask-WTF==0.14.2
gevent==1.2.2
greenlet==0.4.12
html5lib==1.0b8
hurry.filesize==0.9
hypchat==0.21
idna==2.6
infinity==1.4
intervals==0.8.0
itsdangerous==0.24
Jinja2==2.9.5
jira==1.0.10
lazy-object-proxy==1.2.2
lxml==3.8.0
MarkupSafe==1.0
monotonic==1.4
oauthlib==2.0.2
olefile==0.44
ordereddict==1.1
packaging==16.8
pbr==3.0.1
pdfkit==0.6.1
Pillow==4.0.0
pql==0.4.3
psutil==5.4.1
py==1.4.34
pymongo==3.4.0
pyodbc==4.0.15
pyparsing==2.2.0
PyPDF2==1.26.0
pypyodbc==1.3.4
python-dateutil==2.6.0
python-engineio==2.0.1
python-memcached==1.58
python-socketio==1.8.3
pytz==2016.10
reportlab==3.4.0
requests==2.13.0
requests-oauthlib==0.8.0
requests-toolbelt==0.8.0
six==1.10.0
SQLAlchemy==1.1.6
SQLAlchemy-Utils==0.32.14
suds==0.4
urllib3==1.22
validators==0.11.3
vine==1.1.3
webencodings==0.5.1
Werkzeug==0.12
wrapt==1.10.10
WTForms==2.1
xmltodict==0.10.2
WTForms-Components==0.10.3

我已经了解了以下情况:-monkey patch Gevent-通过uwsgi的早期monkey patch Gevent(假设在uwsgi 2.1上工作)-添加Redis队列

是否有其他方法使Flask SocketIO与uWSGI工人同步工作?

共有2个答案

子车超英
2023-03-14

@shalbafzadeh给了我一个惊人的线索。答案是:

uWSGI多工作者模式中的Flask SocketIO需要monkey patchin和一些文档中描述的消息队列机制,如Redis。使Redis工作,解决了描述的问题。以下是Redis部分:

Flask SocketIO需要到redis的连接字符串(代码隐藏使用redis.redis.from_url()方法)。我在发布问题时犯了一个明显的错误,忽略了我的redis受密码保护的事实,所以url实际上如下所示:

'redis://[:RedIsPass#]@localhost:6379/1'

然而,由于密码字符串的规范化并将其加载为主机,错误消息略有误导。它删除了特殊的字符和小写的一切。这让我想到错误msg:

错误-2连接到redispass:6379。名称或服务未知。

当我固定连接字符串:

'redis://:RedIsPass#@localhost:6379/1'

我遇到了另一个问题,这次是“无效IPV6”错误。这是由密码不正确引起的。遗憾的是,Redis lib没有URL解码,因此即使将#替换为#也无法解决问题,因为#以纯文本形式传递,并且与密码不匹配。必须更改服务器上的密码。常规密码完成了任务。

锺离烈
2023-03-14

似乎是redis的问题你安装并启动了吗?运行redis-cli-hlocalhost-p 6379以确保flask-solketIO可以连接到它

 类似资料:
  • 我正在使用flask-RESTful开发API,并且对Flask的jsonify函数有问题。我正在使用flask-marshmlet进行JSON序列化。下面是一个非常简化的代码片段: 在本地,endpoint将返回具有键“data”和“error”的json;但是,当在Linux服务器上运行时,它会返回一个包含列表和在没有“data”和“error”键的情况下返回的结果。 我已经确定这种不一致是由

  • 我发现很难找到有关这方面的资料。会是什么?我如何解决这个问题?有哪些可能的修复方法? UWSGI日志文件 时钟来源:unix检测到CPU核数:4当前工作目录:/home/pi检测到二进制路径:/usr/local/bin/uwsgi!!!没有内部路由支持,重建与pcre支持!!!*警告:您在没有主进程管理器的情况下运行uWSGI进程数限制为7336内存页大小为4096字节检测到最大文件描述符号:6

  • 在过去的几周里,我花了太多的时间试图让它发挥作用。我的目标是使用烧瓶框架创建一个简单的网络应用程序,但我不断收到错误,几个小时的谷歌搜索和搜索stackoverflow也没有帮助。 我正在学习一个教程,该教程要求我运行:$python3 routes.py 只有我才能得到以下错误: 回溯(最近的最后一次调用):文件“routes.py”,第1行,从flask导入flask中,呈现\u模板导入错误:

  • 我已经用flask在python上制作了一个restapi(端口:5000),我正在从一个网站(端口:80)发出get和post请求。我收到了cors错误,所以我尝试在RESTAPI中为站点创建一个响应头。但是我得到了导入错误: 我已经下载了烧瓶cors模块并升级它,并确保它是在正确的路径,但它仍然不工作。 API代码:

  • 我正在使用flask应用程序工厂模式,比如,并运行这个。py文件: 然后我像这样运行应用程序: 但是当我去http://localhost:5000它不起作用。它说: 未找到 在服务器上找不到请求的URL。如果您手动输入URL,请检查拼写并重试。 可能有什么问题?当我有127.0.0.1地址时,它运行良好。。。 我需要在“localhost”上运行,因为我正在集成方形支付,他们的沙盒设置需要我从“

  • 我正在建立一个小网站,我已经在SQLAlChemy中拥有了我所有的模型。该网站将发布一些离线计算的信息。只有结果将被发布到一个精简的数据库,即它包含结果,而不是原始数据,但网站需要查询结果。 我将使用Flask,因为我的模型已经用Python驱动了(通过SWIG在C中进行了一些繁重的工作),我不想使用Django。 我敢肯定,以前有人问过这个问题,通常没有太多理由的咒语是“使用炼金术”。问题是为什