我有一个运行pandas的烧瓶webapp,可以在后端进行一些数据分析.
现在,我采用了朴素的方法,使用AJAX让用户将查询发送回服务器并与数据进行交互.但事实证明每个请求都有很多开销,每次我需要将数据重新加载到pandas/memory中,这是非常重复的.
我认为socketio在这里很有用 - 我会打开一个套接字连接,这样一旦文件加载到pandas中,用户就可以通过套接字以更少的开销响应性地交互和查询数据.
所以我现在的问题是:
我有一个使用以下Procfile托管在heroku上的flask-socketio应用程序:
web: gunicorn --worker-class eventlet hello:app
Run Code Online (Sandbox Code Playgroud)
自从我切换到socketio后,该应用程序一直表现得不一致.之前该应用程序将运行一段时间,然后POST请求将开始超时.
从昨天晚上起,我一直收到错误
sock=backend at=error code=H18 desc="Server Request Interrupted" method=GET path="/static/js/third-party/browser.js" host=deard.herokuapp.com request_id=725da6af-aa29-4293-a411-2c89977f1d4d fwd="216.165.95.0" dyno=web.1 connect=1ms service=36ms status=503 bytes=13811
Run Code Online (Sandbox Code Playgroud)
我阅读了heroku错误代码说明,其中说明"在后端返回HTTP响应之前,属于您应用程序的Web进程的后端套接字已关闭".
但我不知道为什么会发生这种情况.
关于我应该注意什么的任何线索,将帮助我调试这个.
我可以共享代码,但它的300行很长,因为我不知道错误源自何处,我不确定它是否有用.
我正在将烧录应用程序中的音频从客户端传输到服务器,但收到的音频质量非常低.
在客户端,我按如下方式预处理音频缓冲区:
this.node.onaudioprocess = function(e){
var buf = e.inputBuffer.getChannelData(0);
var out = new Int16Array(buf.length);
for (var i = 0; i < buf.length; i++){
var s = Math.max(-1, Math.min(1, buf[i]));
out[i] = s < 0 ? s * 0x8000 : s * 0x7FFF;
}
socket.emit('audio event',{data: out})
return;
}
Run Code Online (Sandbox Code Playgroud)
在服务器端,我收到如下音频:
audio_file = open('tempfile.raw', 'w')
@socketio.on('audio event')
def audio_message(message):
dat = [v[1] for v in sorted(message['data'].iteritems())]
n = len(dat)
byteval = struct.pack('<'+str(n)+'h',*dat)
audio_file.write(byteval)
Run Code Online (Sandbox Code Playgroud)
但由此产生的音频听起来很金属,中断和嘈杂.以下是结果波形的外观:
在我的代码中,音频质量丢失了吗?如何在没有质量损失的情况下传输音频?
我有一个Python Web应用程序,客户端(Ember.js)通过WebSocket与服务器通信(我正在使用Flask-SocketIO).除了WebSocket服务器之外,后端还有两件值得提及的事情:
当客户端提交图像时,在数据库中创建其实体,并将id放入图像转换队列中.工人抓住它并进行图像转换.之后,工作人员将其放入OCR队列,在那里它将由OCR队列工作者处理.
到现在为止还挺好.WS请求在不同的线程中同步处理(Flask-SocketIO使用Eventlet),并且繁重的计算操作异步发生(在单独的线程中也是如此).
现在问题是:整个应用程序在Raspberry Pi 3上运行.如果我没有使用它的4核,我只有一个主频为1.2 GHz的ARMv8内核.这对于OCR来说是非常小的力量.所以我决定了解如何在Python中使用多个内核.虽然我读到了GIL的问题但是我发现了多处理的地方The multiprocessing package offers both local and remote concurrency, effectively side-stepping the Global Interpreter Lock by using subprocesses instead of threads..正是我想要的.所以我立即取代了
from threading import Thread
thread = Thread(target=heavy_computational_worker_thread)
thread.start()
Run Code Online (Sandbox Code Playgroud)
通过
from multiprocessing import Process
process = Process(target=heavy_computational_worker_thread)
process.start()
Run Code Online (Sandbox Code Playgroud)
队列需要由多个核心处理,所以我不得不改变
from queue import Queue
queue = multiprocessing.Queue()
Run Code Online (Sandbox Code Playgroud)
至
import multiprocessing
queue = multiprocessing.Queue()
Run Code Online (Sandbox Code Playgroud)
同样.有问题:队列和线程库由Eventlet …
python multithreading multiprocessing eventlet flask-socketio
使用Websockets运行Flask应用程序时,总是出现此错误。我尝试遵循此指南-http://blog.miguelgrinberg.com/post/easy-websockets-with-flask-and-gevent
我有一个flask应用程序,为我的网络嗅探器提供GUI界面。嗅探器位于线程内,如下所示:(l是我的嗅探器线程; isRunning是一个布尔值,用于检查线程是否已在运行)
try:
if l.isRunning == False: # if the thread has been shut down
l.isRunning = True # change it to true, so it could loop again
running = True
l.start() # starts the forever loop / declared from the top to be a global variable
print str(running)
else:
running = True
print str(running)
l.start()
except Exception, e:
raise e
return flask.render_template('test.html', running=running) #goes to the test.html page
Run Code Online (Sandbox Code Playgroud)
嗅探器在没有socketio的情况下运行良好,我可以在遍历gui的同时嗅探网络。但是,当我在代码中包含socketio时,我首先看到socketio在索引页面中正常工作,并且能够接收来自服务器到页面。我还可以遍历GUI中的其他静态方法;但是,激活线程网络嗅探器会使浏览器挂断。我总是收到异常gevent.hub.LoopExit:LoopExit('此操作将永远阻止',)错误,当我重新运行程序时,控制台会说该地址已被使用。在我看来,这种情况可能无法正确关闭我的套接字。我还认为某些操作正在阻止该错误。我的python flask应用程序中的代码如下所示
def background_thread():
"""Example of how to send …Run Code Online (Sandbox Code Playgroud) 我正在使用Flask构建一个网站,其中我也使用Flask-socketIO使用Websockets ,但有一点我不明白.
我建立了一个聊天功能.当一个用户发送消息时,我使用websockets将该消息发送到服务器,之后我从同一个调用中向另一个用户发送消息:
@socketio.on('newPM', namespace='/test')
@login_required_with_global
def io_newMessage(theJson):
emit('message', {'message': theJson['message']}, room=str(theJson['toUserId']))
Run Code Online (Sandbox Code Playgroud)
但是,假设我想在保存文件时向用户发出消息.这意味着我需要从文件POST的视图中发出消息.所以根据flask_socketio文档,我可以在emit中添加一个名称空间.所以我写了这个:
@app.route('/doc', methods=['POST'])
@login_required
def postDoc():
saveDocument(request.files['file'], g.user.id)
emit('my response', {'data': 'A NEW FILE WAS POSTED'}, room=current_user.id, namespace='/test')
return jsonify({'id': str(doc.id)})
Run Code Online (Sandbox Code Playgroud)
但是看到下面的堆栈跟踪仍然存在命名空间的问题; werkzeug有一个AttributeError: 'Request' object has no attribute 'namespace'.
有谁知道我在这里做错了什么?或者这是flask_socketio中的错误?欢迎所有提示!
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1817, in wsgi_app
response …Run Code Online (Sandbox Code Playgroud) 我正在使用应用程序工厂方法创建一个烧瓶应用程序,但在使用带有socketio和flask-script的Flask-Migrate时出现问题.
问题是我将我的create_app功能传递给了Manager我,但我也需要传递app给我socketio.run().而现在我似乎无法找到解决方案.有什么方法可以将这两种解决方案结合起来吗?
manage.py:
#app = create_app(False) <--- Old approach
#manager = flask_script.Manager(app)
manager = flask_script.Manager(create_app)
manager.add_option("-t", "--testing", dest="testing", required=False)
manager.add_command("run", socketio.run(
app,
host='127.0.0.1',
port=5000,
use_reloader=False)
)
# DB Management
manager.add_command("db", flask_migrate.MigrateCommand)
Run Code Online (Sandbox Code Playgroud)
当我使用旧的方法与socketio,但没有烧瓶 - 迁移一切工作.如果我使用新方法,并删除socketio部分,迁移工作.
注意:我希望能够使用以下两个命令调用我的应用程序.
python manage.py run
python manage.py -t True db upgrade
编辑:
试着用current_app我的意思RuntimeError: working outside of application context
manager.add_command("run", socketio.run(
flask.current_app,
host='127.0.0.1',
port=5000,
use_reloader=False)
)
Run Code Online (Sandbox Code Playgroud) 我正在Flask-SocketIO服务器上工作正常。
但是,我的服务器日志中收到很多这样的请求:
"GET /socket.io/?EIO=3&transport=polling&t=LBS1TQt HTTP/1.1"
这是我正在使用的代码:
from flask import Flask, render_template, redirect, url_for
from flask_socketio import SocketIO, emit
import json
def load_config():
# configuration
return json.load(open('/etc/geekdj/config.json'))
config = load_config()
geekdj = Flask(__name__)
geekdj.config["DEBUG"] = config["debug"]
geekdj.config["SECRET_KEY"] = config["secret_key"]
geekdj.config.from_envvar("FLASKR_SETTINGS", silent=True)
socketio = SocketIO(geekdj)
@geekdj.route('/')
def index():
return render_template('index.html')
# SocketIO functions
@socketio.on('connect')
def chat_connect():
print ('connected')
@socketio.on('disconnect')
def chat_disconnect():
print ("Client disconnected")
@socketio.on('broadcast')
def chat_broadcast(message):
print ("test")
emit("chat", {'data': message['data']})
if __name__ == "__main__":
socketio.run(geekdj, port=8000)
Run Code Online (Sandbox Code Playgroud)
和JS中的index.html:
<script …Run Code Online (Sandbox Code Playgroud) 我想知道如何在我的烧瓶websocket服务器上进行单元测试.我的应用程序支持REST API(Flask-restful)和Web Socket(Flask-SocketIO)上的很多接口.所有websocket"发射"都在芹菜过程中进行.我有问题单元测试那些websocket逻辑.
几个人说,首先我必须分开这个rest-api + websocket应用程序.在单个服务器上运行整个应用程序(逻辑上)是否奇怪?
如何对websocket代码进行单元测试?
谢谢
我正在尝试开发一个支持后端长任务的网络应用程序。我在我的服务器上使用flask-socketio包和芹菜。我的工作流程如下:
我查看了 @Miguels 对39423646/flask-socketio-emit-to-specific-user的回答,它为每个用户创建一个单独的房间,然后在该房间上广播消息。但我想问是否有其他更简单的方法来做到这一点,因为它似乎效率低下或强制的方式来做到这一点。
我还遇到了nodejs解决方案(how-to-send-a-message-to-a-preferred-client-with-socket-io),我觉得这是实现这一目标的更自然的方式。python-socketio 中也有类似的解决方案吗?
更新:经过更多搜索后,我在 github gist 上发现了以下解决方案。据此 -- ** flash-socketIO 已经将所有客户端放在request.sid** 指定的单独房间中。
我仍然希望讨论其他方法来做到这一点。具体来说,如果网站流量相当高,是否会导致房间过多?
更新(2):我当前的(工作)服务器代码使用 rooms。这是从flask-SocketIO celery示例借用并修改的
@celery.task(bind=True)
def long_task(self, userid, url):
# LONG TASK
time.sleep(10)
# meta = some result
post(url, json=meta)
# It seems i can't directly emit from celery function so I mimic a post request and emit from that …Run Code Online (Sandbox Code Playgroud) flask-socketio ×10
flask ×7
python ×7
socket.io ×5
websocket ×3
audio ×1
eventlet ×1
flask-script ×1
heroku ×1
javascript ×1
pack ×1
pandas ×1
unit-testing ×1